Package: kfreebsd-image-9.0-2-amd64 Version: 9.0-10 I found that bind() for Unix domain socket truncates the given socket pathname if the pathname is too long.
bind() should be failed for too long pathnames. POSIX 2001 (IEEE Std 1003.1-2001) defines ENAMETOOLONG error for bind() as follows: | If the address family of the socket is AF_UNIX, then bind() shall fail if: | ... | [ENAMETOOLONG] | A component of a pathname exceeded {NAME_MAX} characters, or an entire | pathname exceeded {PATH_MAX} characters. Other platforms, including GNU/Linux and FreeBSD, fails with ENAMETOOLONG or EINVAL for too long pathnames. The maximum length varies, though. I compared various platforms. The result is here: https://github.com/akr/socket-test http://htmlpreview.github.com/?https://github.com/akr/socket-test/blob/master/results/index.html#unix-stream256c0 The following program reproduce the problem. It specify a pathname with 4108 bytes (including the terminating NUL) to bind() and it succeeds but actual socket pathname length is 104 bytes. The given pathname length is longer than NAME_MAX(255) and PATH_MAX(1024). So bind() should be failed according to POSIX. % uname -srvm GNU/kFreeBSD 9.0-2-amd64 #0 Sat Nov 24 04:44:27 UTC 2012 x86_64 % lsb_release -idrc Distributor ID: Debian Description: Debian GNU/kFreeBSD 7.0 (wheezy) Release: 7.0 Codename: wheezy % ls tst.c % cat tst.c #include <stddef.h> #include <stdlib.h> #include <stdio.h> #include <sys/socket.h> #include <sys/un.h> int main(int argc, char *argv[]) { int s, ret, len; char bigbuf[sizeof(struct sockaddr_un)+4000]; struct sockaddr_un *addr; printf("sizeof(sun_path): %d\n", (int)sizeof(addr->sun_path)); printf("NAME_MAX: %d\n", (int)NAME_MAX); printf("PATH_MAX: %d\n", (int)PATH_MAX); s = socket(AF_UNIX, SOCK_STREAM, 0); if (s == -1) { perror("socket"); exit(EXIT_FAILURE); } addr = (struct sockaddr_un *)bigbuf; memset(addr, '\0', sizeof(bigbuf)); addr->sun_family = AF_UNIX; len = sizeof(bigbuf)-offsetof(struct sockaddr_un, sun_path); printf("socket pathname length: %d\n", len); memset(addr->sun_path, 's', len-1); addr->sun_path[len-1] = '\0'; ret = bind(s, (struct sockaddr *)addr, sizeof(bigbuf)); if (ret == -1) { perror("bind"); exit(EXIT_FAILURE); } printf("bind() succeeds.\n"); exit(EXIT_SUCCESS); } % gcc -Wall tst.c % ./a.out sizeof(sun_path): 104 NAME_MAX: 255 PATH_MAX: 1024 socket pathname length: 4108 bind() succeeds. % ls s*|wc 1 1 105 % ls s*|od -c -Ad 0000000 s s s s s s s s s s s s s s s s * 0000096 s s s s s s s s \n 0000105 % dpkg -l|egrep '\<kfreebsd-image|libc-' ii kfreebsd-image-9-amd64 9.0-10 kfreebsd-amd64 kernel of FreeBSD 9 image (meta-package) ii kfreebsd-image-9.0-2-amd64 9.0-10 kfreebsd-amd64 kernel of FreeBSD 9.0 image ii libc-bin 2.13-38 kfreebsd-amd64 Embedded GNU C Library: Binaries ii libc-dev-bin 2.13-38 kfreebsd-amd64 Embedded GNU C Library: Development binaries Note that it is not clear that bind() should be failed or not for pathnames longer than sizeof(sun_path) but shorter than NAME_MAX. I feel it should also be failed or succeeds with a socket file with given length. The truncation is very unintuitive. -- Tanaka Akira -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org