| 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 <jason.wessel@windriver.com> |
| |
| 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; |