diff options
author | 2019-05-30 12:58:20 +0000 | |
---|---|---|
committer | 2019-05-30 12:58:20 +0000 | |
commit | 0cdadd3f5b3fb589565215b75e8da7f43f83bd6e (patch) | |
tree | 1bf848d66a16bc2c64f1fe94810282f6a55c022b | |
parent | No longer need to reduce line number by one. (diff) | |
download | wireguard-openbsd-0cdadd3f5b3fb589565215b75e8da7f43f83bd6e.tar.xz wireguard-openbsd-0cdadd3f5b3fb589565215b75e8da7f43f83bd6e.zip |
Correct call to vfs_getcwd_common from within __realpath
I borrowed an example usage from __getcwd poorly to begin with
and then there was some other strangeness in there.
diagnosed with deraadt.
ok deraadt@
-rw-r--r-- | sys/kern/vfs_syscalls.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 5b649af01d7..379e0041881 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_syscalls.c,v 1.315 2019/05/13 22:55:27 beck Exp $ */ +/* $OpenBSD: vfs_syscalls.c,v 1.316 2019/05/30 12:58:20 beck Exp $ */ /* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */ /* @@ -875,16 +875,13 @@ sys___realpath(struct proc *p, void *v, register_t *retval) syscallarg(char *) resolved; } */ *uap = v; char *pathname; - char *cwdbuf; char *rpbuf; struct nameidata nd; size_t pathlen; - int cwdlen = MAXPATHLEN * 4; int error = 0; pathname = pool_get(&namei_pool, PR_WAITOK); rpbuf = pool_get(&namei_pool, PR_WAITOK); - cwdbuf = malloc(cwdlen, M_TEMP, M_WAITOK); if ((error = copyinstr(SCARG(uap, pathname), pathname, MAXPATHLEN, &pathlen))) @@ -898,26 +895,30 @@ sys___realpath(struct proc *p, void *v, register_t *retval) /* Get cwd for relative path if needed, prepend to rpbuf */ rpbuf[0] = '\0'; if (pathname[0] != '/') { - char *path, *bp, *bend; - int lenused; + int cwdlen = MAXPATHLEN * 4; /* for vfs_getcwd_common */ + char *cwdbuf, *bp; - bp = &cwdbuf[cwdlen]; - bend = bp; - *(--bp) = '\0'; + cwdbuf = malloc(cwdlen, M_TEMP, M_WAITOK); - error = vfs_getcwd_common(p->p_fd->fd_cdir, NULL, &bp, path, + /* vfs_getcwd_common fills this in backwards */ + bp = &cwdbuf[cwdlen - 1]; + *bp = '\0'; + + error = vfs_getcwd_common(p->p_fd->fd_cdir, NULL, &bp, cwdbuf, cwdlen/2, GETCWD_CHECK_ACCESS, p); - if (error) + if (error) { + free(cwdbuf, M_TEMP, cwdlen); goto end; - - lenused = bend - bp; - *retval = lenused; + } if (strlcpy(rpbuf, bp, MAXPATHLEN) >= MAXPATHLEN) { + free(cwdbuf, M_TEMP, cwdlen); error = ENAMETOOLONG; goto end; } + + free(cwdbuf, M_TEMP, cwdlen); } if (pathlen == 2 && pathname[0] == '/') @@ -952,7 +953,6 @@ sys___realpath(struct proc *p, void *v, register_t *retval) end: pool_put(&namei_pool, rpbuf); pool_put(&namei_pool, pathname); - free(cwdbuf, M_TEMP, cwdlen); return (error); } |