]> Zhao Yanbai Git Server - minix.git/commitdiff
UDS: terminate canonical path string 92/392/2
authorThomas Veerman <thomas@minix3.org>
Fri, 8 Mar 2013 14:17:13 +0000 (14:17 +0000)
committerThomas Veerman <thomas@minix3.org>
Fri, 8 Mar 2013 15:42:32 +0000 (15:42 +0000)
When you provided a string with junk after the terminating nul to a
UNIX domain socket and used bind(2), the canonical path function would
not properly terminate the new string. This caused VFS to return
ENAMETOOLONG on an otherwise valid path name.

Test case is added to test56.

Change-Id: I883b6be23d9e4ea13c3cee28cbb3726343df037f

servers/vfs/path.c
test/test56.c

index 242fe3eb8b816c7d7b46c808baadb12d3b3000fc..6c0d2bbdf29bc1b398b7616aac200233a1556123 100644 (file)
@@ -760,14 +760,14 @@ struct fproc *rfp;
        }
 
        /* now we have to retrieve the name of the parent directory */
-       if (get_name(parent_dir, dir_vp, component) != OK) {
+       if ((r = get_name(parent_dir, dir_vp, component)) != OK) {
                unlock_vnode(parent_dir);
                unlock_vmnt(parent_vmp);
                unlock_vnode(dir_vp);
                unlock_vmnt(dir_vmp);
                put_vnode(parent_dir);
                put_vnode(dir_vp);
-               return(ENOENT);
+               return(r);
        }
 
        len += strlen(component) + 1;
@@ -809,7 +809,7 @@ struct fproc *rfp;
   /* add the leading slash */
   len = strlen(orig_path);
   if (strlen(orig_path) >= PATH_MAX) return(ENAMETOOLONG);
-  memmove(orig_path+1, orig_path, len);
+  memmove(orig_path+1, orig_path, len + 1 /* include terminating nul */);
   orig_path[0] = '/';
 
   /* remove trailing slash if there is any */
index 13751d515a7d62089e0a7b1f8f61a157313ffc7d..eb3b0f33a60b6e29fd27217f351b22dec072955e 100644 (file)
@@ -567,6 +567,21 @@ void test_bind(void)
        UNLINK(TEST_SYM_A);
        UNLINK(TEST_SYM_B);
 
+       /* Test bind with garbage in sockaddr_un */
+       memset(&addr, '?', sizeof(struct sockaddr_un));
+       addr.sun_family = AF_UNIX;
+       addr.sun_path[0] = 'f';
+       addr.sun_path[1] = 'o';
+       addr.sun_path[2] = 'o';
+       addr.sun_path[3] = '\0';
+       SOCKET(sd, PF_UNIX, SOCK_STREAM, 0);
+       rc = bind(sd, (struct sockaddr *) &addr, strlen(addr.sun_path) + 1);
+       if (rc == -1) {
+               test_fail("bind() should have worked");
+       }
+       CLOSE(sd);
+       UNLINK(TEST_SUN_PATH);
+
        debug("leaving test_bind()");
 }