summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2016-04-22 22:31:17 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2016-04-22 22:31:17 +0000
commit585b2e9ac75221a1ca2566a7ae4601e279727eee (patch)
treee22d6a1cfa8cfdf3f1dbb030ba055f67b7d103a9
parent97b9486d984bf215dd22d3c9913df98b1ae683d4 (diff)
downloadillumos-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.c4
-rw-r--r--usr/src/lib/brand/lx/lx_brand/common/misc.c56
-rw-r--r--usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h1
-rw-r--r--usr/src/uts/common/brand/lx/os/lx_syscall.c4
-rw-r--r--usr/src/uts/common/brand/lx/sys/lx_syscalls.h1
-rw-r--r--usr/src/uts/common/brand/lx/syscall/lx_getcwd.c50
-rw-r--r--usr/src/uts/intel/Makefile.files1
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 \