75 lines
2.0 KiB
Diff
75 lines
2.0 KiB
Diff
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;
|