summaryrefslogtreecommitdiff
path: root/usr/src/lib/libc/port
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libc/port')
-rw-r--r--usr/src/lib/libc/port/gen/arc4random.c4
-rw-r--r--usr/src/lib/libc/port/gen/getauxv.c15
-rw-r--r--usr/src/lib/libc/port/gen/sh_locks.c2
-rw-r--r--usr/src/lib/libc/port/gen/siglist.c2
-rw-r--r--usr/src/lib/libc/port/gen/str2sig.c3
-rw-r--r--usr/src/lib/libc/port/mapfile-vers7
-rw-r--r--usr/src/lib/libc/port/stdio/system.c11
-rw-r--r--usr/src/lib/libc/port/sys/inotify.c142
-rw-r--r--usr/src/lib/libc/port/sys/zone.c13
-rw-r--r--usr/src/lib/libc/port/threads/sigaction.c74
-rw-r--r--usr/src/lib/libc/port/threads/thr.c13
11 files changed, 256 insertions, 30 deletions
diff --git a/usr/src/lib/libc/port/gen/arc4random.c b/usr/src/lib/libc/port/gen/arc4random.c
index d82f12bd2a..f60ed09afc 100644
--- a/usr/src/lib/libc/port/gen/arc4random.c
+++ b/usr/src/lib/libc/port/gen/arc4random.c
@@ -2,7 +2,7 @@
* Copyright (c) 1996, David Mazieres <dm@uun.org>
* Copyright (c) 2008, Damien Miller <djm@openbsd.org>
* Copyright (c) 2013, Markus Friedl <markus@openbsd.org>
- * Copyright (c) 2015 Joyent, Inc.
+ * Copyright 2019 Joyent, Inc.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -60,7 +60,7 @@ arc4_init(uint8_t *buf, size_t n)
abort();
chacha_keysetup(&arc4->arc4_chacha, buf, ARC4_KEYSZ * 8, 0);
- chacha_ivsetup(&arc4->arc4_chacha, buf + ARC4_KEYSZ);
+ chacha_ivsetup(&arc4->arc4_chacha, buf + ARC4_KEYSZ, NULL);
}
static void
diff --git a/usr/src/lib/libc/port/gen/getauxv.c b/usr/src/lib/libc/port/gen/getauxv.c
index 500675719c..4356a01392 100644
--- a/usr/src/lib/libc/port/gen/getauxv.c
+++ b/usr/src/lib/libc/port/gen/getauxv.c
@@ -24,9 +24,8 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "lint.h"
+#include "thr_uberdata.h"
#include <libc.h>
#include <fcntl.h>
#include <stdlib.h>
@@ -38,6 +37,7 @@
#include <thread.h>
#include <synch.h>
#include <atomic.h>
+#include <limits.h>
static mutex_t auxlock = DEFAULTMUTEX;
@@ -59,11 +59,20 @@ _getaux(int type)
if (auxb == NULL) {
lmutex_lock(&auxlock);
if (auxb == NULL) {
+ uberdata_t *udp = curthread->ul_uberdata;
struct stat statb;
auxv_t *buf = NULL;
+ char *path = "/proc/self/auxv";
+ char pbuf[PATH_MAX];
int fd;
- if ((fd = open("/proc/self/auxv", O_RDONLY)) != -1 &&
+ if (udp->ub_broot != NULL) {
+ (void) snprintf(pbuf, sizeof (pbuf),
+ "%s/proc/self/auxv", udp->ub_broot);
+ path = pbuf;
+ }
+
+ if ((fd = open(path, O_RDONLY)) != -1 &&
fstat(fd, &statb) != -1)
buf = libc_malloc(
statb.st_size + sizeof (auxv_t));
diff --git a/usr/src/lib/libc/port/gen/sh_locks.c b/usr/src/lib/libc/port/gen/sh_locks.c
index 6583efbc9c..cf879195c6 100644
--- a/usr/src/lib/libc/port/gen/sh_locks.c
+++ b/usr/src/lib/libc/port/gen/sh_locks.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "lint.h"
#include <mtlib.h>
#include <sys/types.h>
diff --git a/usr/src/lib/libc/port/gen/siglist.c b/usr/src/lib/libc/port/gen/siglist.c
index 441cc4c2c5..bc6dc1b731 100644
--- a/usr/src/lib/libc/port/gen/siglist.c
+++ b/usr/src/lib/libc/port/gen/siglist.c
@@ -22,6 +22,7 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015, Joyent, Inc.
*/
/* Copyright (c) 1988 AT&T */
@@ -128,6 +129,7 @@ static const char *_sys_siglist_data[NSIG] = {
"Fourteenth Realtime Signal", /* SIGRTMIN+13 */
"Fifteenth Realtime Signal", /* SIGRTMIN+14 */
"Sixteenth Realtime Signal", /* SIGRTMIN+15 */
+ "Seventeenth Realtime Signal", /* SIGRTMIN+16 */
"Sixteenth Last Realtime Signal", /* SIGRTMAX-15 */
"Fifteenth Last Realtime Signal", /* SIGRTMAX-14 */
"Fourteenth Last Realtime Signal", /* SIGRTMAX-13 */
diff --git a/usr/src/lib/libc/port/gen/str2sig.c b/usr/src/lib/libc/port/gen/str2sig.c
index e0c4e89d68..02c6f3cb65 100644
--- a/usr/src/lib/libc/port/gen/str2sig.c
+++ b/usr/src/lib/libc/port/gen/str2sig.c
@@ -22,7 +22,7 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- * Copyright (c) 2014, Joyent, Inc. All rights reserved.
+ * Copyright 2015, Joyent, Inc.
*/
/* Copyright (c) 1988 AT&T */
@@ -102,6 +102,7 @@ static signame_t signames[] = {
{ "RTMIN+13", _SIGRTMIN+13 },
{ "RTMIN+14", _SIGRTMIN+14 },
{ "RTMIN+15", _SIGRTMIN+15 },
+ { "RTMIN+16", _SIGRTMIN+16 },
{ "RTMAX-15", _SIGRTMAX-15 },
{ "RTMAX-14", _SIGRTMAX-14 },
{ "RTMAX-13", _SIGRTMAX-13 },
diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers
index 0e1cafc04e..9ccd7c528e 100644
--- a/usr/src/lib/libc/port/mapfile-vers
+++ b/usr/src/lib/libc/port/mapfile-vers
@@ -3695,6 +3695,10 @@ $endif
__idmap_unreg;
__init_daemon_priv;
__init_suid_priv;
+ inotify_init;
+ inotify_init1;
+ inotify_add_watch;
+ inotify_rm_watch;
_insert;
inst_sync;
_iswctype;
@@ -3799,7 +3803,9 @@ $endif
psecflags_validate;
semctl64;
_semctl64;
+ set_escaped_context_cleanup;
set_setcontext_enforcement;
+ setcontext_sigmask;
_setbufend;
__set_errno;
setprojrctl;
@@ -3916,6 +3922,7 @@ $endif
zone_list;
zone_list_datalink;
zonept;
+ zone_get_nroot;
zone_remove_datalink;
zone_setattr;
zone_shutdown;
diff --git a/usr/src/lib/libc/port/stdio/system.c b/usr/src/lib/libc/port/stdio/system.c
index bc7e412d52..698d02b2ec 100644
--- a/usr/src/lib/libc/port/stdio/system.c
+++ b/usr/src/lib/libc/port/stdio/system.c
@@ -22,6 +22,7 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2016 Joyent, Inc.
*/
/* Copyright (c) 1988 AT&T */
@@ -43,6 +44,7 @@
#include <synch.h>
#include <spawn.h>
#include <paths.h>
+#include <zone.h>
#include "libc.h"
extern const char **_environ;
@@ -125,11 +127,18 @@ system(const char *cmd)
int error;
sigset_t mask;
struct stat64 buf;
- const char *shpath = _PATH_BSHELL;
+ char shpath[MAXPATHLEN];
+ const char *zroot = zone_get_nroot();
char *argv[4];
posix_spawnattr_t attr;
static const char *shell = "sh";
+ /*
+ * If executing in brand use native root.
+ */
+ (void) snprintf(shpath, sizeof (shpath), "%s%s",
+ zroot != NULL ? zroot : "", _PATH_BSHELL);
+
if (cmd == NULL) {
if (stat64(shpath, &buf) != 0) {
return (0);
diff --git a/usr/src/lib/libc/port/sys/inotify.c b/usr/src/lib/libc/port/sys/inotify.c
new file mode 100644
index 0000000000..90d04b5dd3
--- /dev/null
+++ b/usr/src/lib/libc/port/sys/inotify.c
@@ -0,0 +1,142 @@
+/*
+ * 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 (c) 2014, Joyent, Inc. All rights reserved.
+ */
+
+#include <sys/inotify.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <strings.h>
+#include <dirent.h>
+
+int
+inotify_init()
+{
+ return (open("/dev/inotify", O_RDWR));
+}
+
+int
+inotify_init1(int flags)
+{
+ int oflags = O_RDWR;
+
+ if (flags & IN_NONBLOCK)
+ oflags |= O_NONBLOCK;
+
+ if (flags & IN_CLOEXEC)
+ oflags |= O_CLOEXEC;
+
+ return (open("/dev/inotify", oflags));
+}
+
+int
+inotify_add_watch(int fd, const char *pathname, uint32_t mask)
+{
+ inotify_addwatch_t ioc;
+ inotify_addchild_t cioc;
+ struct stat buf;
+ int dirfd, wd;
+ DIR *dir;
+ struct dirent *dp;
+ int oflags = O_RDONLY;
+
+ if (mask & IN_DONT_FOLLOW)
+ oflags |= O_NOFOLLOW;
+
+ if ((dirfd = open(pathname, oflags)) < 0)
+ return (-1);
+
+ if (fstat(dirfd, &buf) != 0) {
+ (void) close(dirfd);
+ return (-1);
+ }
+
+ if ((mask & IN_ONLYDIR) && !(buf.st_mode & S_IFDIR)) {
+ (void) close(dirfd);
+ errno = ENOTDIR;
+ return (-1);
+ }
+
+ bzero(&ioc, sizeof (ioc));
+ ioc.inaw_fd = dirfd;
+ ioc.inaw_mask = mask;
+
+ if ((wd = ioctl(fd, INOTIFYIOC_ADD_WATCH, &ioc)) < 0) {
+ (void) close(dirfd);
+ return (-1);
+ }
+
+ if (!(buf.st_mode & S_IFDIR) || !(mask & IN_CHILD_EVENTS)) {
+ (void) close(dirfd);
+ (void) ioctl(fd, INOTIFYIOC_ACTIVATE, wd);
+ return (wd);
+ }
+
+ /*
+ * If we have a directory and we have a mask that denotes child events,
+ * we need to manually add a child watch to every directory entry.
+ * (Because our watch is in place, it will automatically be added to
+ * files that are newly created after this point.)
+ */
+ if ((dir = fdopendir(dirfd)) == NULL) {
+ (void) inotify_rm_watch(fd, wd);
+ (void) close(dirfd);
+ return (-1);
+ }
+
+ bzero(&cioc, sizeof (cioc));
+ cioc.inac_fd = dirfd;
+
+ while ((dp = readdir(dir)) != NULL) {
+ if (strcmp(dp->d_name, ".") == 0)
+ continue;
+
+ if (strcmp(dp->d_name, "..") == 0)
+ continue;
+
+ cioc.inac_name = dp->d_name;
+
+ if (ioctl(fd, INOTIFYIOC_ADD_CHILD, &cioc) != 0) {
+ /*
+ * If we get an error that indicates clear internal
+ * malfunctioning, we propagate the error. Otherwise
+ * we eat it: this could be a file that no longer
+ * exists or a symlink or something else that we
+ * can't lookup.
+ */
+ switch (errno) {
+ case ENXIO:
+ case EFAULT:
+ case EBADF:
+ (void) closedir(dir);
+ (void) inotify_rm_watch(fd, wd);
+ return (-1);
+ default:
+ break;
+ }
+ }
+ }
+
+ (void) closedir(dir);
+ (void) ioctl(fd, INOTIFYIOC_ACTIVATE, wd);
+
+ return (wd);
+}
+
+int
+inotify_rm_watch(int fd, int wd)
+{
+ return (ioctl(fd, INOTIFYIOC_RM_WATCH, wd));
+}
diff --git a/usr/src/lib/libc/port/sys/zone.c b/usr/src/lib/libc/port/sys/zone.c
index 4a4c70043d..8cf28c3ccf 100644
--- a/usr/src/lib/libc/port/sys/zone.c
+++ b/usr/src/lib/libc/port/sys/zone.c
@@ -22,9 +22,11 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2011 Joyent Inc. All rights reserved.
*/
#include "lint.h"
+#include "thr_uberdata.h"
#include <sys/types.h>
#include <sys/syscall.h>
#include <sys/zone.h>
@@ -39,7 +41,8 @@
zoneid_t
zone_create(const char *name, const char *root, const struct priv_set *privs,
const char *rctls, size_t rctlsz, const char *zfs, size_t zfssz,
- int *extended_error, int match, int doi, const bslabel_t *label, int flags)
+ int *extended_error, int match, int doi, const bslabel_t *label, int flags,
+ zoneid_t req_zoneid)
{
zone_def zd;
priv_data_t *d;
@@ -59,6 +62,7 @@ zone_create(const char *name, const char *root, const struct priv_set *privs,
zd.doi = doi;
zd.label = label;
zd.flags = flags;
+ zd.zoneid = req_zoneid;
return ((zoneid_t)syscall(SYS_zone, ZONE_CREATE, &zd));
}
@@ -241,3 +245,10 @@ zone_list_datalink(zoneid_t zoneid, int *dlnump, datalink_id_t *linkids)
{
return (syscall(SYS_zone, ZONE_LIST_DATALINK, zoneid, dlnump, linkids));
}
+
+const char *
+zone_get_nroot()
+{
+ uberdata_t *udp = curthread->ul_uberdata;
+ return (udp->ub_broot);
+}
diff --git a/usr/src/lib/libc/port/threads/sigaction.c b/usr/src/lib/libc/port/threads/sigaction.c
index 1417c1e18a..8c48989a17 100644
--- a/usr/src/lib/libc/port/threads/sigaction.c
+++ b/usr/src/lib/libc/port/threads/sigaction.c
@@ -22,6 +22,7 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2015 Joyent, Inc.
*/
/*
@@ -288,6 +289,24 @@ take_deferred_signal(int sig)
thr_panic("take_deferred_signal(): __sigresend() failed");
}
+/*
+ * sigacthandler() attempts to clean up dangling uc_link pointers in
+ * signal handling contexts when libc believes us to have escaped
+ * a signal handler incorrectly in the past.
+ *
+ * Branded processes have a legitimate use for a chain including contexts
+ * other than those used for signal handling when tracking emulation
+ * requests from the kernel. We allow them to disable this cleanup
+ * behaviour.
+ */
+static int escaped_context_cleanup = 1;
+
+void
+set_escaped_context_cleanup(int on)
+{
+ escaped_context_cleanup = on;
+}
+
void
sigacthandler(int sig, siginfo_t *sip, void *uvp)
{
@@ -310,7 +329,7 @@ sigacthandler(int sig, siginfo_t *sip, void *uvp)
* we are actually executing at main level (self->ul_siglink == NULL).
* See the code for setjmp()/longjmp() for more details.
*/
- if (self->ul_siglink == NULL)
+ if (escaped_context_cleanup && self->ul_siglink == NULL)
ucp->uc_link = NULL;
/*
@@ -462,11 +481,12 @@ sigaction(int sig, const struct sigaction *nact, struct sigaction *oact)
}
/*
- * This is a private interface for the linux brand interface.
+ * This is a private interface for the lx brand.
*/
void
setsigacthandler(void (*nsigacthandler)(int, siginfo_t *, void *),
- void (**osigacthandler)(int, siginfo_t *, void *))
+ void (**osigacthandler)(int, siginfo_t *, void *),
+ int (*brsetctxt)(const ucontext_t *))
{
ulwp_t *self = curthread;
uberdata_t *udp = self->ul_uberdata;
@@ -475,6 +495,9 @@ setsigacthandler(void (*nsigacthandler)(int, siginfo_t *, void *),
*osigacthandler = udp->sigacthandler;
udp->sigacthandler = nsigacthandler;
+
+ if (brsetctxt != NULL)
+ udp->setctxt = brsetctxt;
}
/*
@@ -521,11 +544,39 @@ set_setcontext_enforcement(int on)
setcontext_enforcement = on;
}
+/*
+ * The LX brand emulation library implements an operation that is analogous to
+ * setcontext(), but takes a different path in to the kernel. So that it can
+ * correctly restore a signal mask, we expose just the signal mask handling
+ * part of the regular setcontext() routine as a private interface.
+ */
+void
+setcontext_sigmask(ucontext_t *ucp)
+{
+ ulwp_t *self = curthread;
+
+ if (ucp->uc_flags & UC_SIGMASK) {
+ block_all_signals(self);
+ delete_reserved_signals(&ucp->uc_sigmask);
+ self->ul_sigmask = ucp->uc_sigmask;
+ if (self->ul_cursig) {
+ /*
+ * We have a deferred signal present.
+ * The signal mask will be set when the
+ * signal is taken in take_deferred_signal().
+ */
+ ASSERT(self->ul_critical + self->ul_sigdefer != 0);
+ ucp->uc_flags &= ~UC_SIGMASK;
+ }
+ }
+}
+
#pragma weak _setcontext = setcontext
int
setcontext(const ucontext_t *ucp)
{
ulwp_t *self = curthread;
+ uberdata_t *udp = self->ul_uberdata;
int ret;
ucontext_t uc;
@@ -540,20 +591,7 @@ setcontext(const ucontext_t *ucp)
/*
* Restore previous signal mask and context link.
*/
- if (uc.uc_flags & UC_SIGMASK) {
- block_all_signals(self);
- delete_reserved_signals(&uc.uc_sigmask);
- self->ul_sigmask = uc.uc_sigmask;
- if (self->ul_cursig) {
- /*
- * We have a deferred signal present.
- * The signal mask will be set when the
- * signal is taken in take_deferred_signal().
- */
- ASSERT(self->ul_critical + self->ul_sigdefer != 0);
- uc.uc_flags &= ~UC_SIGMASK;
- }
- }
+ setcontext_sigmask(&uc);
self->ul_siglink = uc.uc_link;
/*
@@ -588,7 +626,7 @@ setcontext(const ucontext_t *ucp)
*/
set_parking_flag(self, 0);
self->ul_sp = 0;
- ret = __setcontext(&uc);
+ ret = udp->setctxt(&uc);
/*
* It is OK for setcontext() to return if the user has not specified
diff --git a/usr/src/lib/libc/port/threads/thr.c b/usr/src/lib/libc/port/threads/thr.c
index 0ee28c0c59..d8bf7799f4 100644
--- a/usr/src/lib/libc/port/threads/thr.c
+++ b/usr/src/lib/libc/port/threads/thr.c
@@ -127,6 +127,7 @@ uberdata_t __uberdata = {
0, /* ndaemons */
0, /* pid */
sigacthandler, /* sigacthandler */
+ __setcontext, /* setctxt */
NULL, /* lwp_stacks */
NULL, /* lwp_laststack */
0, /* nfreestack */
@@ -139,6 +140,7 @@ uberdata_t __uberdata = {
NULL, /* robustlocks */
NULL, /* robustlist */
NULL, /* progname */
+ NULL, /* ub_broot */
NULL, /* ub_comm_page */
NULL, /* __tdb_bootstrap */
{ /* tdb */
@@ -1232,13 +1234,19 @@ init_auxv_data(uberdata_t *udp)
{
Dl_argsinfo_t args;
+ udp->ub_broot = NULL;
udp->ub_comm_page = NULL;
if (dlinfo(RTLD_SELF, RTLD_DI_ARGSINFO, &args) < 0)
return;
while (args.dla_auxv->a_type != AT_NULL) {
- if (args.dla_auxv->a_type == AT_SUN_COMMPAGE) {
+ switch (args.dla_auxv->a_type) {
+ case AT_SUN_BRAND_NROOT:
+ udp->ub_broot = args.dla_auxv->a_un.a_ptr;
+ break;
+ case AT_SUN_COMMPAGE:
udp->ub_comm_page = args.dla_auxv->a_un.a_ptr;
+ break;
}
args.dla_auxv++;
}
@@ -1282,7 +1290,8 @@ libc_init(void)
/*
* Every libc, regardless of link map, needs to go through and check
* its aux vectors. Doing so will indicate whether or not this has
- * been given a comm page (to optimize certain system actions).
+ * been given a brand root (used to qualify various other data) or a
+ * comm page (to optimize certain system actions).
*/
init_auxv_data(udp);