Hi. I found that connect() access bytes after socket address.
The test program below specifies a same struct sockaddr_un for bind() and connect(). I expect connect() success but "connect: No such file or directory" error occured. rpctrace shows that bind() binds a socket as the socket file "AB" and connect() try to connect for the socket file "ABCD". This is caused by the socket address and its length. The socket address is AF_UNIX and sun_path field is "AB" The socket length is offsetof(struct sockaddr_un, sun_path) + 2. However sun_path field has garbage "CD\0" just after "AB". It seems that bind() properly uses the socket length and connect() doesn't use that. The problem is the socket address is not NUL terminated. Strictly speaking, this is not POSIX confoming because POSIX defines sun_path is pathname and pathname is terminated by NUL. However I think this behavior is a bug of connect() because 1. bind() and connect() consistency and 2. accessing undefined bytes is a really bad idea. % uname -srvm GNU 0.3 GNU-Mach 1.3.99-486/Hurd-0.3 i686-AT386 % 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, c, ret; struct sockaddr_un addr; socklen_t addrlen; s = socket(AF_UNIX, SOCK_STREAM, 0); if (s == -1) { perror("socket"); exit(EXIT_FAILURE); } addrlen = offsetof(struct sockaddr_un, sun_path) + 2; addr.sun_family = AF_UNIX; addr.sun_path[0] = 'A'; addr.sun_path[1] = 'B'; addr.sun_path[2] = 'C'; addr.sun_path[3] = 'D'; addr.sun_path[4] = '\0'; ret = bind(s, (struct sockaddr *)&addr, addrlen); if (s == -1) { perror("bind"); exit(EXIT_FAILURE); } ret = listen(s, SOMAXCONN); if (ret == -1) { perror("listen"); exit(EXIT_FAILURE); } c = socket(AF_UNIX, SOCK_STREAM, 0); if (c == -1) { perror("socket"); exit(EXIT_FAILURE); } ret = connect(c, (struct sockaddr *)&addr, addrlen); if (ret == -1) { perror("connect"); exit(EXIT_FAILURE); } return EXIT_SUCCESS; } % gcc -Wall tst.c % ls a.out tst.c % ./a.out connect: No such file or directory % ls AB a.out tst.c % rm AB % rpctrace ./a.out |& grep AB 92<--119(pid565)->dir_link ( 136<--135(pid565) "AB" 1) = 0 92<--119(pid565)->dir_lookup ("AB" 0 0) = 0 1 "" 136<--137(pid565) 92<--119(pid565)->dir_lookup ("ABCD" 0 0) = 0x40000002 (No such file or directory) % -- Tanaka Akira