blob: 219dd35aec23a0b69ea0e6a553e4b3e55cf2fe07 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001nfs.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;