nfs.c: Allow max sa.sun_path for a localdomain socket with the user nfs-server There is a hard limit for the kernel of 108 characters for a localdomain socket name. To avoid problems with the user nfs server it should maximize the number of characters by using a relative path on the server side. Previously the nfs-server used the absolute path name passed to the sa.sunpath arg for binding the socket and this has caused problems for both the X server and UST binaries which make heavy use of named sockets with long names. Signed-off-by: Jason Wessel Upstream-Status: Submitted http://sourceforge.net/p/unfs3/bugs/5/ --- nfs.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) --- a/nfs.c +++ b/nfs.c @@ -672,6 +672,7 @@ SYMLINK3res *nfsproc3_symlink_3_svc(SYML } #ifndef WIN32 +static char pathbuf_tmp[NFS_MAXPATHLEN + NFS_MAXNAMLEN + 1]; /* * create Unix socket @@ -680,17 +681,41 @@ static int mksocket(const char *path, mo { int res, sock; struct sockaddr_un addr; + unsigned int len = strlen(path); sock = socket(PF_UNIX, SOCK_STREAM, 0); - addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, path); res = sock; if (res != -1) { + addr.sun_family = AF_UNIX; + if (len < sizeof(addr.sun_path) -1) { + strcpy(addr.sun_path, path); + } else { + char *ptr; + res = -1; + if (len >= sizeof(path)) + goto out; + strcpy(pathbuf_tmp, path); + ptr = strrchr(pathbuf_tmp,'/'); + if (ptr) { + *ptr = '\0'; + ptr++; + if (chdir(pathbuf_tmp)) + goto out; + } else { + ptr = pathbuf_tmp; + } + if (strlen(ptr) >= sizeof(addr.sun_path)) + goto out; + strcpy(addr.sun_path, ptr); + } umask(~mode); res = bind(sock, (struct sockaddr *) &addr, sizeof(addr.sun_family) + strlen(addr.sun_path)); umask(0); +out: + if (chdir("/")) + fprintf(stderr, "Internal failure to chdir /\n"); close(sock); } return res;