xref: /OK3568_Linux_fs/yocto/poky/meta/recipes-devtools/unfs3/unfs3/relative_max_socket_path_len.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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