diff options
| author | Joshua M. Clulow <jmc@joyent.com> | 2015-02-25 16:43:20 -0800 |
|---|---|---|
| committer | Joshua M. Clulow <jmc@joyent.com> | 2015-02-26 00:43:20 +0000 |
| commit | 890385b39da8bb050f8fa40ed15adb891808f66c (patch) | |
| tree | b59dc8638376572cba151a970d875b871d31f26e | |
| parent | 4d8fab53f98471367ec2f1aaa7078b0e67104522 (diff) | |
| download | illumos-joyent-890385b39da8bb050f8fa40ed15adb891808f66c.tar.gz | |
OS-3923 lxbrand in-kernel chmod(2), fchmod(2) and fchmodat(2)
OS-3920 lxbrand use native *at(2) system calls for LX emulation
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
| -rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/file.c | 43 | ||||
| -rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/lx_brand.c | 15 | ||||
| -rw-r--r-- | usr/src/lib/brand/lx/lx_brand/common/misc.c | 9 | ||||
| -rw-r--r-- | usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h | 3 | ||||
| -rw-r--r-- | usr/src/uts/common/brand/lx/os/lx_brand.c | 8 | ||||
| -rw-r--r-- | usr/src/uts/common/brand/lx/os/lx_syscall.c | 12 | ||||
| -rw-r--r-- | usr/src/uts/common/brand/lx/sys/lx_brand.h | 9 | ||||
| -rw-r--r-- | usr/src/uts/common/brand/lx/sys/lx_fcntl.h (renamed from usr/src/lib/brand/lx/lx_brand/sys/lx_fcntl.h) | 37 | ||||
| -rw-r--r-- | usr/src/uts/common/brand/lx/sys/lx_syscalls.h | 15 | ||||
| -rw-r--r-- | usr/src/uts/common/brand/lx/syscall/lx_chmod.c | 70 | ||||
| -rw-r--r-- | usr/src/uts/intel/Makefile.files | 1 |
11 files changed, 143 insertions, 79 deletions
diff --git a/usr/src/lib/brand/lx/lx_brand/common/file.c b/usr/src/lib/brand/lx/lx_brand/common/file.c index 1f2c4032f5..a3fc081c53 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/file.c +++ b/usr/src/lib/brand/lx/lx_brand/common/file.c @@ -316,29 +316,6 @@ lx_fchown(uintptr_t p1, uintptr_t p2, uintptr_t p3) } long -lx_chmod(uintptr_t p1, uintptr_t p2) -{ - int ret; - - ret = chmod((const char *)p1, (mode_t)p2); - - if (ret < 0) { - /* - * If chown() failed and we're in install mode, return success - * if the the reason we failed was because the source file - * didn't actually exist or if we're trying to modify /dev/pts. - */ - if ((lx_install != 0) && - ((errno == ENOENT) || (install_checkpath(p1) == 0))) - return (0); - - return (-errno); - } - - return (0); -} - -long lx_utime(uintptr_t p1, uintptr_t p2) { int ret; @@ -868,23 +845,3 @@ lx_fchownat(uintptr_t ext1, uintptr_t p1, uintptr_t p2, uintptr_t p3, else return (lx_chown((uintptr_t)pathbuf, p2, p3)); } - -/*ARGSUSED*/ -long -lx_fchmodat(uintptr_t ext1, uintptr_t p1, uintptr_t p2, uintptr_t p3) -{ - int atfd = (int)ext1; - char pathbuf[MAXPATHLEN]; - int ret; - - /* - * It seems that at least some versions of glibc do not set or clear - * the flags arg, so checking them will result in random behaviour. - */ - - ret = getpathat(atfd, p1, pathbuf, sizeof (pathbuf)); - if (ret < 0) - return (ret); - - return (lx_chmod((uintptr_t)pathbuf, p2)); -} 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 5c5dd53fff..3b88397860 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 @@ -583,6 +583,8 @@ lx_init(int argc, char *argv[], char *envp[]) void *vdso_hdr; #endif + bzero(®, sizeof (reg)); + stack_bottom = 2 * sysconf(_SC_PAGESIZE); /* @@ -621,6 +623,7 @@ lx_init(int argc, char *argv[], char *envp[]) * Are we in install mode? */ if (getenv("LX_INSTALL") != NULL) { + reg.lxbr_flags |= LX_PROC_INSTALL_MODE; lx_install = 1; lx_debug("INSTALL mode enabled.\n"); } @@ -1049,8 +1052,8 @@ static lx_syscall_handler_t lx_handlers[] = { lx_unlink, /* 87: unlink */ lx_symlink, /* 88: symlink */ lx_readlink, /* 89: readlink */ - lx_chmod, /* 90: chmod */ - lx_fchmod, /* 91: fchmod */ + NULL, /* 90: chmod */ + NULL, /* 91: fchmod */ lx_chown, /* 92: chown */ lx_fchown, /* 93: fchown */ lx_lchown, /* 94: lchown */ @@ -1227,7 +1230,7 @@ static lx_syscall_handler_t lx_handlers[] = { lx_linkat, /* 265: linkat */ lx_symlinkat, /* 266: symlinkat */ lx_readlinkat, /* 267: readlinkat */ - lx_fchmodat, /* 268: fchmodat */ + NULL, /* 268: fchmodat */ lx_faccessat, /* 269: faccessat */ lx_pselect6, /* 270: pselect6 */ lx_ppoll, /* 271: ppoll */ @@ -1305,7 +1308,7 @@ static lx_syscall_handler_t lx_handlers[] = { lx_chdir, /* 12: chdir */ lx_time, /* 13: time */ lx_mknod, /* 14: mknod */ - lx_chmod, /* 15: chmod */ + NULL, /* 15: chmod */ lx_lchown16, /* 16: lchown16 */ NULL, /* 17: break */ NULL, /* 18: stat */ @@ -1384,7 +1387,7 @@ static lx_syscall_handler_t lx_handlers[] = { lx_munmap, /* 91: munmap */ lx_truncate, /* 92: truncate */ lx_ftruncate, /* 93: ftruncate */ - lx_fchmod, /* 94: fchmod */ + NULL, /* 94: fchmod */ lx_fchown16, /* 95: fchown16 */ lx_getpriority, /* 96: getpriority */ lx_setpriority, /* 97: setpriority */ @@ -1596,7 +1599,7 @@ static lx_syscall_handler_t lx_handlers[] = { lx_linkat, /* 303: linkat */ lx_symlinkat, /* 304: symlinkat */ lx_readlinkat, /* 305: readlinkat */ - lx_fchmodat, /* 306: fchmodat */ + NULL, /* 306: fchmodat */ lx_faccessat, /* 307: faccessat */ lx_pselect6, /* 308: pselect6 */ lx_ppoll, /* 309: ppoll */ 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 7e16fb717e..e3bb34dadc 100644 --- a/usr/src/lib/brand/lx/lx_brand/common/misc.c +++ b/usr/src/lib/brand/lx/lx_brand/common/misc.c @@ -823,15 +823,6 @@ lx_fchdir(int fildes) return ((r == -1) ? -errno : r); } -long -lx_fchmod(int fildes, mode_t mode) -{ - int r; - - r = fchmod(fildes, mode); - return ((r == -1) ? -errno : r); -} - /* * We support neither the second argument (NUMA node), nor the third (obsolete * pre-2.6.24 caching functionality which was ultimately broken). 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 4cc72ba0c6..7aed33752f 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 @@ -56,7 +56,6 @@ extern long lx_renameat(uintptr_t, uintptr_t, uintptr_t, uintptr_t); extern long lx_linkat(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t); extern long lx_symlinkat(uintptr_t, uintptr_t, uintptr_t); extern long lx_readlinkat(uintptr_t, uintptr_t, uintptr_t, uintptr_t); -extern long lx_fchmodat(uintptr_t, uintptr_t, uintptr_t, uintptr_t); extern long lx_access(uintptr_t, uintptr_t); extern long lx_faccessat(uintptr_t, uintptr_t, uintptr_t, uintptr_t); @@ -184,7 +183,6 @@ extern long lx_fchown16(uintptr_t, uintptr_t, uintptr_t); extern long lx_lchown16(uintptr_t, uintptr_t, uintptr_t); extern long lx_chown(uintptr_t, uintptr_t, uintptr_t); extern long lx_fchown(uintptr_t, uintptr_t, uintptr_t); -extern long lx_chmod(uintptr_t, uintptr_t); extern long lx_rename(uintptr_t, uintptr_t); extern long lx_utime(uintptr_t, uintptr_t); extern long lx_llseek(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t); @@ -319,7 +317,6 @@ extern long lx_epoll_wait(int, void *, int, int); extern long lx_eventfd(unsigned int); extern long lx_eventfd2(unsigned int, int); extern long lx_fchdir(int); -extern long lx_fchmod(int, mode_t); extern long lx_getgid(void); extern long lx_getgroups(int, gid_t *); extern long lx_getitimer(int, struct itimerval *); diff --git a/usr/src/uts/common/brand/lx/os/lx_brand.c b/usr/src/uts/common/brand/lx/os/lx_brand.c index fc9aaa6055..a2f38da9dd 100644 --- a/usr/src/uts/common/brand/lx/os/lx_brand.c +++ b/usr/src/uts/common/brand/lx/os/lx_brand.c @@ -805,6 +805,7 @@ lx_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, reg.lxbr_version = (uint_t)reg32.lxbr_version; reg.lxbr_handler = (void *)(uintptr_t)reg32.lxbr_handler; + reg.lxbr_flags = reg32.lxbr_flags; } #endif @@ -814,10 +815,17 @@ lx_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, return (EINVAL); } + if ((reg.lxbr_flags & ~LX_PROC_ALL) != 0) { + lx_print("Invalid brand flags (%u)\n", + reg.lxbr_flags); + return (EINVAL); + } + lx_print("Assigning brand 0x%p and handler 0x%p to proc 0x%p\n", (void *)&lx_brand, (void *)reg.lxbr_handler, (void *)p); pd = p->p_brand_data; pd->l_handler = (uintptr_t)reg.lxbr_handler; + pd->l_flags = reg.lxbr_flags; return (0); 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 09a3e9bbba..eb4ce1e8f6 100644 --- a/usr/src/uts/common/brand/lx/os/lx_syscall.c +++ b/usr/src/uts/common/brand/lx/os/lx_syscall.c @@ -441,7 +441,7 @@ lx_sysent_t lx_sysent32[] = { {"chdir", NULL, 0, 1}, /* 12 */ {"time", NULL, 0, 1}, /* 13 */ {"mknod", NULL, 0, 3}, /* 14 */ - {"chmod", NULL, 0, 2}, /* 15 */ + {"chmod", lx_chmod, 0, 2}, /* 15 */ {"lchown16", NULL, 0, 3}, /* 16 */ {"break", NULL, NOSYS_OBSOLETE, 0}, /* 17 */ {"stat", NULL, NOSYS_OBSOLETE, 0}, /* 18 */ @@ -520,7 +520,7 @@ lx_sysent_t lx_sysent32[] = { {"munmap", NULL, 0, 2}, /* 91 */ {"truncate", NULL, 0, 2}, /* 92 */ {"ftruncate", NULL, 0, 2}, /* 93 */ - {"fchmod", NULL, 0, 2}, /* 94 */ + {"fchmod", lx_fchmod, 0, 2}, /* 94 */ {"fchown16", NULL, 0, 3}, /* 95 */ {"getpriority", NULL, 0, 2}, /* 96 */ {"setpriority", NULL, 0, 3}, /* 97 */ @@ -736,7 +736,7 @@ lx_sysent_t lx_sysent32[] = { {"linkat", NULL, 0, 5}, /* 303 */ {"symlinkat", NULL, 0, 3}, /* 304 */ {"readlinkat", NULL, 0, 4}, /* 305 */ - {"fchmodat", NULL, 0, 4}, /* 306 */ + {"fchmodat", lx_fchmodat, 0, 3}, /* 306 */ {"faccessat", NULL, 0, 4}, /* 307 */ {"pselect6", NULL, LX_SYS_EBPARG6, 6}, /* 308 */ {"ppoll", NULL, 0, 5}, /* 309 */ @@ -887,8 +887,8 @@ lx_sysent_t lx_sysent64[] = { {"unlink", NULL, 0, 1}, /* 87 */ {"symlink", NULL, 0, 2}, /* 88 */ {"readlink", NULL, 0, 3}, /* 89 */ - {"chmod", NULL, 0, 2}, /* 90 */ - {"fchmod", NULL, 0, 2}, /* 91 */ + {"chmod", lx_chmod, 0, 2}, /* 90 */ + {"fchmod", lx_fchmod, 0, 2}, /* 91 */ {"chown", NULL, 0, 3}, /* 92 */ {"fchown", NULL, 0, 3}, /* 93 */ {"lchown", NULL, 0, 3}, /* 94 */ @@ -1065,7 +1065,7 @@ lx_sysent_t lx_sysent64[] = { {"linkat", NULL, 0, 5}, /* 265 */ {"symlinkat", NULL, 0, 3}, /* 266 */ {"readlinkat", NULL, 0, 4}, /* 267 */ - {"fchmodat", NULL, 0, 4}, /* 268 */ + {"fchmodat", lx_fchmodat, 0, 3}, /* 268 */ {"faccessat", NULL, 0, 4}, /* 269 */ {"pselect6", NULL, 0, 6}, /* 270 */ {"ppoll", NULL, 0, 5}, /* 271 */ diff --git a/usr/src/uts/common/brand/lx/sys/lx_brand.h b/usr/src/uts/common/brand/lx/sys/lx_brand.h index 543373b5fa..f3c46dd7fd 100644 --- a/usr/src/uts/common/brand/lx/sys/lx_brand.h +++ b/usr/src/uts/common/brand/lx/sys/lx_brand.h @@ -203,11 +203,13 @@ extern struct brand lx_brand; typedef struct lx_brand_registration { uint_t lxbr_version; /* version number */ void *lxbr_handler; /* base address of handler */ + uint32_t lxbr_flags; /* LX_PROC_* registration flags */ } lx_brand_registration_t; typedef struct lx_brand_registration32 { uint_t lxbr_version; /* version number */ uint32_t lxbr_handler; /* base address of handler */ + uint32_t lxbr_flags; /* LX_PROC_* registration flags */ } lx_brand_registration32_t; #ifdef __amd64 @@ -392,6 +394,12 @@ typedef lx_elf_data64_t lx_elf_data_t; typedef lx_elf_data32_t lx_elf_data_t; #endif +typedef enum lx_proc_flags { + LX_PROC_INSTALL_MODE = 0x01 +} lx_proc_flags_t; + +#define LX_PROC_ALL LX_PROC_INSTALL_MODE + #ifdef _KERNEL typedef struct lx_proc_data { @@ -401,6 +409,7 @@ typedef struct lx_proc_data { lx_elf_data_t l_elf_data; /* ELF data for linux executable */ int l_signal; /* signal to deliver to parent when this */ /* thread group dies */ + lx_proc_flags_t l_flags; } lx_proc_data_t; #endif /* _KERNEL */ diff --git a/usr/src/lib/brand/lx/lx_brand/sys/lx_fcntl.h b/usr/src/uts/common/brand/lx/sys/lx_fcntl.h index 06e05cbf5c..f3b472e7ff 100644 --- a/usr/src/lib/brand/lx/lx_brand/sys/lx_fcntl.h +++ b/usr/src/uts/common/brand/lx/sys/lx_fcntl.h @@ -21,7 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * Copyright 2014 Joyent, Inc. All rights reserved. + * Copyright 2015 Joyent, Inc. */ #ifndef _SYS_LX_FCNTL_H @@ -94,7 +94,7 @@ extern "C" { * AT_REMOVEDIR is used only by unlinkat and AT_EACCESS is used only by * faccessat. */ -#define LX_AT_FDCWD -100 +#define LX_AT_FDCWD (-100) #define LX_AT_SYMLINK_NOFOLLOW 0x100 #define LX_AT_REMOVEDIR 0x200 #define LX_AT_EACCESS 0x200 @@ -102,21 +102,46 @@ extern "C" { #define LX_AT_NO_AUTOMOUNT 0x800 #define LX_AT_EMPTY_PATH 0x1000 -struct lx_flock { +typedef struct lx_flock { short l_type; short l_whence; long l_start; long l_len; int l_pid; -}; +} lx_flock_t; -struct lx_flock64 { +typedef struct lx_flock64 { short l_type; short l_whence; long long l_start; long long l_len; int l_pid; -}; +} lx_flock64_t; + +#if defined(_KERNEL) && defined(_SYSCALL32_IMPL) + +/* + * 64-bit kernel view of 32-bit usermode structs. + */ +#pragma pack(4) +typedef struct lx_flock32 { + int16_t l_type; + int16_t l_whence; + int32_t l_start; + int32_t l_len; + int32_t l_pid; +} lx_flock32_t; + +typedef struct lx_flock64_32 { + int16_t l_type; + int16_t l_whence; + int64_t l_start; + int64_t l_len; + int32_t l_pid; +} lx_flock64_32_t; +#pragma pack() + +#endif /* _KERNEL && _SYSCALL32_IMPL */ #ifdef __cplusplus } 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 2d9abf2fe6..6943b40310 100644 --- a/usr/src/uts/common/brand/lx/sys/lx_syscalls.h +++ b/usr/src/uts/common/brand/lx/sys/lx_syscalls.h @@ -36,19 +36,20 @@ extern "C" { extern long lx_arch_prctl(); extern long lx_brk(); +extern long lx_chmod(); +extern long lx_fchmod(); +extern long lx_fchmodat(); +extern long lx_futex(); +extern long lx_get_thread_area(); extern long lx_getpid(); extern long lx_getppid(); +extern long lx_gettid(); +extern long lx_ioctl(); extern long lx_kill(); -extern long lx_tkill(); -extern long lx_tgkill(); extern long lx_modify_ldt(); extern long lx_pipe(); extern long lx_pipe2(); extern long lx_read(); -extern long lx_ioctl(); -extern long lx_gettid(); -extern long lx_futex(); -extern long lx_get_thread_area(); extern long lx_sched_getparam(); extern long lx_sched_getscheduler(); extern long lx_sched_rr_get_interval(); @@ -63,6 +64,8 @@ extern long lx_setresuid(); extern long lx_setresuid16(); extern long lx_sysinfo32(); extern long lx_sysinfo64(); +extern long lx_tgkill(); +extern long lx_tkill(); extern long lx_wait4(); extern long lx_waitid(); extern long lx_waitpid(); diff --git a/usr/src/uts/common/brand/lx/syscall/lx_chmod.c b/usr/src/uts/common/brand/lx/syscall/lx_chmod.c new file mode 100644 index 0000000000..66a4e35a63 --- /dev/null +++ b/usr/src/uts/common/brand/lx/syscall/lx_chmod.c @@ -0,0 +1,70 @@ +/* + * 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 2015 Joyent, Inc. + */ + +#include <sys/fcntl.h> +#include <sys/thread.h> +#include <sys/klwp.h> +#include <sys/lx_brand.h> +#include <sys/lx_fcntl.h> + +/* + * From "uts/common/syscall/chmod.c": + */ +extern int fchmodat(int, char *, int, int); + +static long +lx_fchmodat_wrapper(int fd, char *path, int mode, int flag) +{ + long rval; + + if (fd == LX_AT_FDCWD) { + fd = AT_FDCWD; + } + + if ((rval = fchmodat(fd, path, mode, flag)) != 0) { + lx_proc_data_t *pd = ttolxproc(curthread); + klwp_t *lwp = ttolwp(curthread); + + /* + * If the process is in "install mode", return success + * if the operation failed due to an absent file. + */ + if ((pd->l_flags & LX_PROC_INSTALL_MODE) && + lwp->lwp_errno == ENOENT) { + lwp->lwp_errno = 0; + return (0); + } + } + + return (rval); +} + +long +lx_fchmodat(int fd, char *path, int mode) +{ + return (lx_fchmodat_wrapper(fd, path, mode, 0)); +} + +long +lx_fchmod(int fd, int mode) +{ + return (lx_fchmodat_wrapper(fd, NULL, mode, 0)); +} + +long +lx_chmod(char *path, int mode) +{ + return (lx_fchmodat_wrapper(AT_FDCWD, path, mode, 0)); +} diff --git a/usr/src/uts/intel/Makefile.files b/usr/src/uts/intel/Makefile.files index 7eefb1c062..0b99fc7e9c 100644 --- a/usr/src/uts/intel/Makefile.files +++ b/usr/src/uts/intel/Makefile.files @@ -279,6 +279,7 @@ LX_BRAND_OBJS = \ lx_archdep.o \ lx_brand.o \ lx_brk.o \ + lx_chmod.o \ lx_clone.o \ lx_futex.o \ lx_getpid.o \ |
