UDS: terminate canonical path string
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
This commit is contained in:
parent
08283d6d4d
commit
76ddef10da
2 changed files with 18 additions and 3 deletions
|
@ -760,14 +760,14 @@ struct fproc *rfp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now we have to retrieve the name of the parent directory */
|
/* 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_vnode(parent_dir);
|
||||||
unlock_vmnt(parent_vmp);
|
unlock_vmnt(parent_vmp);
|
||||||
unlock_vnode(dir_vp);
|
unlock_vnode(dir_vp);
|
||||||
unlock_vmnt(dir_vmp);
|
unlock_vmnt(dir_vmp);
|
||||||
put_vnode(parent_dir);
|
put_vnode(parent_dir);
|
||||||
put_vnode(dir_vp);
|
put_vnode(dir_vp);
|
||||||
return(ENOENT);
|
return(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
len += strlen(component) + 1;
|
len += strlen(component) + 1;
|
||||||
|
@ -809,7 +809,7 @@ struct fproc *rfp;
|
||||||
/* add the leading slash */
|
/* add the leading slash */
|
||||||
len = strlen(orig_path);
|
len = strlen(orig_path);
|
||||||
if (strlen(orig_path) >= PATH_MAX) return(ENAMETOOLONG);
|
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] = '/';
|
orig_path[0] = '/';
|
||||||
|
|
||||||
/* remove trailing slash if there is any */
|
/* remove trailing slash if there is any */
|
||||||
|
|
|
@ -567,6 +567,21 @@ void test_bind(void)
|
||||||
UNLINK(TEST_SYM_A);
|
UNLINK(TEST_SYM_A);
|
||||||
UNLINK(TEST_SYM_B);
|
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()");
|
debug("leaving test_bind()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue