blob: 219dd35aec23a0b69ea0e6a553e4b3e55cf2fe07 [file] [log] [blame]
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;