1nfs.c: Allow max sa.sun_path for a localdomain socket with the user nfs-server 2 3There is a hard limit for the kernel of 108 characters for a 4localdomain socket name. To avoid problems with the user nfs 5server it should maximize the number of characters by using 6a relative path on the server side. 7 8Previously the nfs-server used the absolute path name passed to 9the sa.sunpath arg for binding the socket and this has caused 10problems for both the X server and UST binaries which make 11heavy use of named sockets with long names. 12 13Signed-off-by: Jason Wessel <jason.wessel@windriver.com> 14 15Upstream-Status: Submitted http://sourceforge.net/p/unfs3/bugs/5/ 16 17--- 18 nfs.c | 29 +++++++++++++++++++++++++++-- 19 1 file changed, 27 insertions(+), 2 deletions(-) 20 21--- a/nfs.c 22+++ b/nfs.c 23@@ -672,6 +672,7 @@ SYMLINK3res *nfsproc3_symlink_3_svc(SYML 24 } 25 26 #ifndef WIN32 27+static char pathbuf_tmp[NFS_MAXPATHLEN + NFS_MAXNAMLEN + 1]; 28 29 /* 30 * create Unix socket 31@@ -680,17 +681,41 @@ static int mksocket(const char *path, mo 32 { 33 int res, sock; 34 struct sockaddr_un addr; 35+ unsigned int len = strlen(path); 36 37 sock = socket(PF_UNIX, SOCK_STREAM, 0); 38- addr.sun_family = AF_UNIX; 39- strcpy(addr.sun_path, path); 40 res = sock; 41 if (res != -1) { 42+ addr.sun_family = AF_UNIX; 43+ if (len < sizeof(addr.sun_path) -1) { 44+ strcpy(addr.sun_path, path); 45+ } else { 46+ char *ptr; 47+ res = -1; 48+ if (len >= sizeof(path)) 49+ goto out; 50+ strcpy(pathbuf_tmp, path); 51+ ptr = strrchr(pathbuf_tmp,'/'); 52+ if (ptr) { 53+ *ptr = '\0'; 54+ ptr++; 55+ if (chdir(pathbuf_tmp)) 56+ goto out; 57+ } else { 58+ ptr = pathbuf_tmp; 59+ } 60+ if (strlen(ptr) >= sizeof(addr.sun_path)) 61+ goto out; 62+ strcpy(addr.sun_path, ptr); 63+ } 64 umask(~mode); 65 res = 66 bind(sock, (struct sockaddr *) &addr, 67 sizeof(addr.sun_family) + strlen(addr.sun_path)); 68 umask(0); 69+out: 70+ if (chdir("/")) 71+ fprintf(stderr, "Internal failure to chdir /\n"); 72 close(sock); 73 } 74 return res; 75