Skip to content

Commit

Permalink
OS-4474 lxbrand missing prctl(PR_SET_PDEATHSIG) support
Browse files Browse the repository at this point in the history
OS-4476 lxbrand convert prctl to IKE
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
  • Loading branch information
pfmooney committed Jul 6, 2015
1 parent b6d4e43 commit f11c746
Show file tree
Hide file tree
Showing 14 changed files with 265 additions and 130 deletions.
22 changes: 22 additions & 0 deletions usr/src/common/brand/lx/lx_signum.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,28 @@ lx_stol_signo(int signo, int defsig)
return (rval);
}


/*
* Convert a Linux signal number to an illumos signal number and return it.
* Error behavior is identical to lx_stol_signo.
*/
int
lx_ltos_signo(int signo, int defsig)
{
#ifdef _KERNEL
VERIFY3S(defsig, >=, 0);
#endif

if (signo < 1 || signo >= NSIG) {
#ifndef _KERNEL
VERIFY3S(defsig, >=, 0);
#endif
return (defsig);
}

return (ltos_signo[signo]);
}

/*
* Convert the "status" field of a SIGCLD siginfo_t. We need to extract the
* illumos signal number and convert it to a Linux signal number while leaving
Expand Down
1 change: 1 addition & 0 deletions usr/src/common/brand/lx/lx_signum.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ extern const int ltos_signo[];
extern const int stol_signo[];

extern int lx_stol_signo(int, int);
extern int lx_ltos_signo(int, int);
extern int lx_stol_status(int, int);
extern int lx_stol_sigcode(int);

Expand Down
4 changes: 2 additions & 2 deletions usr/src/lib/brand/lx/lx_brand/common/lx_brand.c
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,7 @@ static lx_syscall_handler_t lx_handlers[] = {
NULL, /* 154: modify_ldt */
NULL, /* 155: pivot_root */
lx_sysctl, /* 156: sysctl */
lx_prctl, /* 157: prctl */
NULL, /* 157: prctl */
NULL, /* 158: arch_prctl */
lx_adjtimex, /* 159: adjtimex */
NULL, /* 160: setrlimit */
Expand Down Expand Up @@ -1417,7 +1417,7 @@ static lx_syscall_handler_t lx_handlers[] = {
NULL, /* 169: nfsservctl */
NULL, /* 170: setresgid16 */
lx_getresgid16, /* 171: getresgid16 */
lx_prctl, /* 172: prctl */
NULL, /* 172: prctl */
lx_rt_sigreturn, /* 173: rt_sigreturn */
lx_rt_sigaction, /* 174: rt_sigaction */
lx_rt_sigprocmask, /* 175: rt_sigprocmask */
Expand Down
100 changes: 0 additions & 100 deletions usr/src/lib/brand/lx/lx_brand/common/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,106 +602,6 @@ lx_setgroups(uintptr_t p1, uintptr_t p2)
return ((r == -1) ? -errno : r);
}

/*
* Linux currently defines 42 options for prctl (PR_CAPBSET_READ,
* PR_CAPBSET_DROP, etc.). Most of these are not emulated.
*/
long
lx_prctl(int option, uintptr_t arg2, uintptr_t arg3,
uintptr_t arg4, uintptr_t arg5)
{
psinfo_t psinfo;
size_t fnamelen = sizeof (psinfo.pr_fname);
size_t psargslen = sizeof (psinfo.pr_psargs);
int fd;

if (option == LX_PR_GET_DUMPABLE) {
/* Indicate that process is always dumpable */
return (1);
}

if (option == LX_PR_GET_SECUREBITS) {
/* Our bits are always 0 */
return (0);
}

if (option == LX_PR_SET_SECUREBITS) {
/* Ignore setting any bits from arg2 */
return (0);
}

if (option == LX_PR_SET_DUMPABLE) {
if (arg2 != 1 && arg2 != 0)
return (-EINVAL);
/* Lie about altering process dumpability */
return (0);
}

if (option == LX_PR_SET_KEEPCAPS) {
/*
* The closest illumos analog to SET_KEEPCAPS is the PRIV_AWARE
* flag. There are probably some cases where it's not exactly
* the same, but this will do for a first try.
*/
if (arg2 == 0) {
if (setpflags(PRIV_AWARE_RESET, 1) != 0)
return (-errno);
} else {
if (setpflags(PRIV_AWARE, 1) != 0)
return (-errno);
}
return (0);
}

if (option != LX_PR_SET_NAME) {
lx_unsupported("prctl option %d", option);
return (-ENOSYS);
}

/*
* In Linux, PR_SET_NAME sets the name of the thread, not the process.
* Due to the historical quirks of Linux's asinine thread model, this
* name is effectively the name of the process (as visible via ps(1))
* if the thread is the first of its task group. The first thread is
* therefore special, and to best mimic Linux semantics (and absent a
* notion of per-LWP names), we do nothing (but return success) on LWPs
* other than LWP 1.
*/
if (thr_self() != 1)
return (0);

if (uucopy((void *)arg2, psinfo.pr_fname,
MIN(LX_PR_SET_NAME_NAMELEN, fnamelen)) != 0)
return (-errno);

psinfo.pr_fname[fnamelen - 1] = '\0';

if (uucopy((void *)arg2, psinfo.pr_psargs,
MIN(LX_PR_SET_NAME_NAMELEN, psargslen)) != 0)
return (-errno);

psinfo.pr_psargs[psargslen - 1] = '\0';

if ((fd = open("/native/proc/self/psinfo", O_WRONLY)) < 0)
return (-errno);

if (pwrite(fd, psinfo.pr_fname, fnamelen,
(uintptr_t)psinfo.pr_fname - (uintptr_t)&psinfo) != fnamelen) {
(void) close(fd);
return (-EIO);
}

if (pwrite(fd, psinfo.pr_psargs, psargslen,
(uintptr_t)psinfo.pr_psargs - (uintptr_t)&psinfo) != psargslen) {
(void) close(fd);
return (-EIO);
}

(void) close(fd);

return (0);
}

/*
* For syslog(), as there is no kernel and nothing to log, we simply emulate a
* kernel cyclic buffer (LOG_BUF_LEN) of 0 bytes, only handling errors for bad
Expand Down
13 changes: 0 additions & 13 deletions usr/src/lib/brand/lx/lx_brand/sys/lx_misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,6 @@ extern pid_t zoneinit_pid;
#define LX_RUSAGE_BOTH (-2)
#define LX_RUSAGE_THREAD 1

/*
* Constants for prctl(). We only include the ones here that we actually
* support; everything else will be ENOSYS.
*/
#define LX_PR_GET_DUMPABLE 3
#define LX_PR_SET_DUMPABLE 4
#define LX_PR_SET_KEEPCAPS 8
#define LX_PR_SET_NAME 15
#define LX_PR_GET_SECUREBITS 27
#define LX_PR_SET_SECUREBITS 28

#define LX_PR_SET_NAME_NAMELEN 16

/*
* Based on code from brand_misc.h, but use of that is incompatible with the
* lx brand.
Expand Down
2 changes: 0 additions & 2 deletions usr/src/lib/brand/lx/lx_brand/sys/lx_syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,6 @@ extern long lx_shmget(key_t, size_t, int);
extern long lx_shmat(int, void *, int);
extern long lx_shmctl(int, int, void *);

extern long lx_prctl(int, uintptr_t, uintptr_t, uintptr_t, uintptr_t);

extern long lx_alarm(unsigned int);
extern long lx_close(int);
extern long lx_chdir(const char *);
Expand Down
2 changes: 0 additions & 2 deletions usr/src/lib/brand/lx/testing/Readme_ltp
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,6 @@ x open01 need PRIV_SYS_CONFIG to set sticky bit on reg file
# open10 setgid on sgid subdir behavior
x open11 makes device
# ppoll01
# prctl01 get/set deathsig
# prctl02 more deathsig
# process_vm_readv01
# process_vm_readv02
# process_vm_readv03
Expand Down
2 changes: 0 additions & 2 deletions usr/src/lib/brand/lx/testing/ltp_skiplist
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,6 @@ open10
perf_event_open01
perf_event_open02
ppoll01
prctl01
prctl02
process_vm_readv01
process_vm_readv02
process_vm_readv03
Expand Down
29 changes: 26 additions & 3 deletions usr/src/uts/common/brand/lx/os/lx_brand.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,31 @@ static struct modlinkage modlinkage = {
void
lx_proc_exit(proc_t *p)
{
VERIFY(p->p_brand == &lx_brand);
VERIFY(p->p_brand_data != NULL);
lx_proc_data_t *lxpd;
proc_t *cp;

mutex_enter(&p->p_lock);
VERIFY(lxpd = ptolxproc(p));
if ((lxpd->l_flags & LX_PROC_CHILD_DEATHSIG) == 0) {
mutex_exit(&p->p_lock);
return;
}
mutex_exit(&p->p_lock);

/* Check for children which desire notification of parental death. */
mutex_enter(&pidlock);
for (cp = p->p_child; cp != NULL; cp = cp->p_sibling) {
mutex_enter(&cp->p_lock);
if ((lxpd = ptolxproc(cp)) == NULL) {
mutex_exit(&cp->p_lock);
continue;
}
if (lxpd->l_parent_deathsig != 0) {
sigtoproc(p, NULL, lxpd->l_parent_deathsig);
}
mutex_exit(&cp->p_lock);
}
mutex_exit(&pidlock);
}

void
Expand Down Expand Up @@ -879,7 +902,7 @@ lx_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
(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;
pd->l_flags = reg.lxbr_flags & LX_PROC_ALL;

return (0);

Expand Down
4 changes: 2 additions & 2 deletions usr/src/uts/common/brand/lx/os/lx_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ lx_sysent_t lx_sysent32[] = {
{"nfsservctl", NULL, NOSYS_KERNEL, 0}, /* 169 */
{"setresgid16", lx_setresgid16, 0, 3}, /* 170 */
{"getresgid16", NULL, 0, 3}, /* 171 */
{"prctl", NULL, 0, 5}, /* 172 */
{"prctl", lx_prctl, 0, 5}, /* 172 */
{"rt_sigreturn", NULL, 0, 0}, /* 173 */
{"rt_sigaction", NULL, 0, 4}, /* 174 */
{"rt_sigprocmask", NULL, 0, 4}, /* 175 */
Expand Down Expand Up @@ -1051,7 +1051,7 @@ lx_sysent_t lx_sysent64[] = {
{"modify_ldt", lx_modify_ldt, 0, 3}, /* 154 */
{"pivot_root", NULL, NOSYS_KERNEL, 0}, /* 155 */
{"sysctl", NULL, 0, 1}, /* 156 */
{"prctl", NULL, 0, 5}, /* 157 */
{"prctl", lx_prctl, 0, 5}, /* 157 */
{"arch_prctl", lx_arch_prctl, 0, 2}, /* 158 */
{"adjtimex", NULL, 0, 1}, /* 159 */
{"setrlimit", lx_setrlimit, 0, 2}, /* 160 */
Expand Down
13 changes: 9 additions & 4 deletions usr/src/uts/common/brand/lx/sys/lx_brand.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,11 @@ typedef lx_elf_data32_t lx_elf_data_t;
#endif

typedef enum lx_proc_flags {
LX_PROC_INSTALL_MODE = 0x01,
LX_PROC_STRICT_MODE = 0x02
/* flags configurable via brandsys() and members of LX_PROC_ALL */
LX_PROC_INSTALL_MODE = 0x01,
LX_PROC_STRICT_MODE = 0x02,
/* internal flags */
LX_PROC_CHILD_DEATHSIG = 0x04
} lx_proc_flags_t;

#define LX_PROC_ALL (LX_PROC_INSTALL_MODE | LX_PROC_STRICT_MODE)
Expand All @@ -398,8 +401,10 @@ typedef struct lx_proc_data {
pid_t l_ppid; /* pid of originating parent proc */
uint64_t l_ptrace; /* process being observed with ptrace */
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 */
/* signal to deliver to parent when this thread group dies */
int l_signal;
/* native signal to deliver to process when parent dies */
int l_parent_deathsig;
lx_proc_flags_t l_flags;

lx_rlimit64_t l_fake_limits[LX_RLFAKE_NLIMITS];
Expand Down
1 change: 1 addition & 0 deletions usr/src/uts/common/brand/lx/sys/lx_syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ extern long lx_open();
extern long lx_openat();
extern long lx_pipe();
extern long lx_pipe2();
extern long lx_prctl();
extern long lx_prlimit64();
extern long lx_read();
extern long lx_recv();
Expand Down

0 comments on commit f11c746

Please sign in to comment.