diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-04-22 22:31:17 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2016-04-22 22:31:17 +0000 |
commit | 585b2e9ac75221a1ca2566a7ae4601e279727eee (patch) | |
tree | e22d6a1cfa8cfdf3f1dbb030ba055f67b7d103a9 | |
parent | 97b9486d984bf215dd22d3c9913df98b1ae683d4 (diff) | |
download | illumos-joyent-585b2e9ac75221a1ca2566a7ae4601e279727eee.tar.gz |
OS-5356 su reports getcwd() error in LX zone
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/lx_brand.c | 4 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/misc.c | 56 | ||||
-rw-r--r-- | usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h | 1 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/os/lx_syscall.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/sys/lx_syscalls.h | 1 | ||||
-rw-r--r-- | usr/src/uts/common/brand/lx/syscall/lx_getcwd.c | 50 | ||||
-rw-r--r-- | usr/src/uts/intel/Makefile.files | 1 |
7 files changed, 56 insertions, 61 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c index e7d5ddccc3..7024a5d567 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c +++ b/usr/src/lib/brand/lx/lx_brand/common/lx_brand.c @@ -1042,7 +1042,7 @@ static lx_syscall_handler_t lx_handlers[] = { lx_truncate, /* 76: truncate */ lx_ftruncate, /* 77: ftruncate */ NULL, /* 78: getdents */ - lx_getcwd, /* 79: getcwd */ + NULL, /* 79: getcwd */ lx_chdir, /* 80: chdir */ lx_fchdir, /* 81: fchdir */ lx_rename, /* 82: rename */ @@ -1477,7 +1477,7 @@ static lx_syscall_handler_t lx_handlers[] = { NULL, /* 180: pread64 */ NULL, /* 181: pwrite64 */ NULL, /* 182: chown16 */ - lx_getcwd, /* 183: getcwd */ + NULL, /* 183: getcwd */ lx_capget, /* 184: capget */ lx_capset, /* 185: capset */ lx_sigaltstack, /* 186: sigaltstack */ diff --git a/usr/src/lib/brand/lx/lx_brand/common/misc.c b/usr/src/lib/brand/lx/lx_brand/common/misc.c index 378e766666..e8d60c4696 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/misc.c +++ b/usr/src/lib/brand/lx/lx_brand/common/misc.c @@ -172,62 +172,6 @@ lx_reboot(uintptr_t p1, uintptr_t p2, uintptr_t p3, uintptr_t p4) } /* - * getcwd() - Linux syscall semantics are slightly different; we need to return - * the length of the pathname copied (+ 1 for the terminating NULL byte.) - */ -long -lx_getcwd(uintptr_t p1, uintptr_t p2) -{ - char *buf; - size_t buflen = (size_t)p2; - size_t copylen, local_len; - size_t len = 0; - - if ((getcwd((char *)p1, (size_t)p2)) == NULL) - return (-errno); - - /* - * We need the length of the pathname getcwd() copied but we never want - * to dereference a Linux pointer for any reason. - * - * Thus, to get the string length we will uucopy() up to copylen - * bytes at a time into a local buffer and will walk each chunk looking - * for the string-terminating NULL byte. - * - * We can use strlen() to find the length of the string in the - * local buffer by delimiting the buffer with a NULL byte in the - * last element that will never be overwritten. - */ - copylen = min(buflen, MAXPATHLEN + 1); - buf = SAFE_ALLOCA(copylen + 1); - if (buf == NULL) - return (-ENOMEM); - buf[copylen] = '\0'; - - for (;;) { - if (uucopy((char *)p1 + len, buf, copylen) != 0) - return (-errno); - - local_len = strlen(buf); - len += local_len; - - /* - * If the strlen() is less than copylen, we found the - * real end of the string -- not the NULL byte used to - * delimit the end of our buffer. - */ - if (local_len != copylen) - break; - - /* prepare to check the next chunk of the string */ - buflen -= copylen; - copylen = min(buflen, copylen); - } - - return (len + 1); -} - -/* * {get,set}groups16() - Handle the conversion between 16-bit Linux gids and * 32-bit illumos gids. */ diff --git a/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h b/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h index 5c9c0d9d7f..4b2e23def8 100644 --- a/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h +++ b/usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h @@ -142,7 +142,6 @@ extern long lx_llseek(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t); extern long lx_lseek(uintptr_t, uintptr_t, uintptr_t); extern long lx_sysfs(uintptr_t, uintptr_t, uintptr_t); -extern long lx_getcwd(uintptr_t, uintptr_t); extern long lx_uname(uintptr_t); extern long lx_reboot(uintptr_t, uintptr_t, uintptr_t, uintptr_t); extern long lx_getgroups16(uintptr_t, uintptr_t); diff --git a/usr/src/uts/common/brand/lx/os/lx_syscall.c b/usr/src/uts/common/brand/lx/os/lx_syscall.c index 5e0f03cc5c..23010b8234 100644 --- a/usr/src/uts/common/brand/lx/os/lx_syscall.c +++ b/usr/src/uts/common/brand/lx/os/lx_syscall.c @@ -799,7 +799,7 @@ lx_sysent_t lx_sysent32[] = { {"pread64", lx_pread32, 0, 5}, /* 180 */ {"pwrite64", lx_pwrite32, 0, 5}, /* 181 */ {"chown16", lx_chown16, 0, 3}, /* 182 */ - {"getcwd", NULL, 0, 2}, /* 183 */ + {"getcwd", lx_getcwd, 0, 2}, /* 183 */ {"capget", NULL, 0, 2}, /* 184 */ {"capset", NULL, 0, 2}, /* 185 */ {"sigaltstack", NULL, 0, 2}, /* 186 */ @@ -1066,7 +1066,7 @@ lx_sysent_t lx_sysent64[] = { {"truncate", NULL, 0, 2}, /* 76 */ {"ftruncate", NULL, 0, 2}, /* 77 */ {"getdents", lx_getdents_64, 0, 3}, /* 78 */ - {"getcwd", NULL, 0, 2}, /* 79 */ + {"getcwd", lx_getcwd, 0, 2}, /* 79 */ {"chdir", NULL, 0, 1}, /* 80 */ {"fchdir", NULL, 0, 1}, /* 81 */ {"rename", NULL, 0, 2}, /* 82 */ diff --git a/usr/src/uts/common/brand/lx/sys/lx_syscalls.h b/usr/src/uts/common/brand/lx/sys/lx_syscalls.h index f932c70bb9..001be273cd 100644 --- a/usr/src/uts/common/brand/lx/sys/lx_syscalls.h +++ b/usr/src/uts/common/brand/lx/sys/lx_syscalls.h @@ -70,6 +70,7 @@ extern long lx_futex(); extern long lx_get_robust_list(); extern long lx_get_thread_area(); extern long lx_getcpu(); +extern long lx_getcwd(); extern long lx_getdents_32(); extern long lx_getdents_64(); extern long lx_getdents64(); diff --git a/usr/src/uts/common/brand/lx/syscall/lx_getcwd.c b/usr/src/uts/common/brand/lx/syscall/lx_getcwd.c new file mode 100644 index 0000000000..7fcc594d81 --- /dev/null +++ b/usr/src/uts/common/brand/lx/syscall/lx_getcwd.c @@ -0,0 +1,50 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Joyent, Inc. + */ + +#include <sys/systm.h> +#include <sys/types.h> +#include <sys/proc.h> +#include <sys/vnode.h> +#include <sys/pathname.h> + +/* + * getcwd() - Linux syscall semantics are slightly different; we need to return + * the length of the pathname copied (+ 1 for the terminating NULL byte.) + */ +long +lx_getcwd(char *buf, int size) +{ + int len; + int error; + vnode_t *vp; + char path[MAXPATHLEN + 1]; + + vp = PTOU(curproc)->u_cdir; + VN_HOLD(vp); + if ((error = vnodetopath(NULL, vp, path, sizeof (path), CRED())) != 0) { + VN_RELE(vp); + return (set_errno(error)); + } + VN_RELE(vp); + + len = strlen(path) + 1; + if (len > size) + return (set_errno(ERANGE)); + + if (copyout(path, buf, len) != 0) + return (set_errno(EFAULT)); + + return (len); +} diff --git a/usr/src/uts/intel/Makefile.files b/usr/src/uts/intel/Makefile.files index a3812170c9..81326bb74a 100644 --- a/usr/src/uts/intel/Makefile.files +++ b/usr/src/uts/intel/Makefile.files @@ -305,6 +305,7 @@ LX_BRAND_OBJS = \ lx_fallocate.o \ lx_fcntl.o \ lx_futex.o \ + lx_getcwd.o \ lx_getdents.o \ lx_getpid.o \ lx_getrandom.o \ |