X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=80dbf73c947d4f501503b2cc3626f28c8afff289;hb=73020ab241866dce79b80cbebcaae537470c7086;hp=b5ffaa1c3ccc0f6bff8cc7e5bfdf728a019efa3d;hpb=5e2b3214aa6e9bb3559552d2218ce2eda312c1fc;p=elogind.git diff --git a/src/shared/util.c b/src/shared/util.c index b5ffaa1c3..80dbf73c9 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -86,7 +86,7 @@ static volatile unsigned cached_columns = 0; static volatile unsigned cached_lines = 0; size_t page_size(void) { - static __thread size_t pgsz = 0; + static thread_local size_t pgsz = 0; long r; if (_likely_(pgsz > 0)) @@ -2737,9 +2737,9 @@ int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct _pure_ static int is_temporary_fs(struct statfs *s) { assert(s); - return - F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) || - F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC); + + return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) || + F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC); } int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) { @@ -4580,7 +4580,7 @@ char *strjoin(const char *x, ...) { } bool is_main_thread(void) { - static __thread int cached = 0; + static thread_local int cached = 0; if (_unlikely_(cached == 0)) cached = getpid() == gettid() ? 1 : -1; @@ -4798,7 +4798,7 @@ static const char *const __signal_table[] = { DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int); const char *signal_to_string(int signo) { - static __thread char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1]; + static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1]; const char *name; name = __signal_to_string(signo); @@ -4936,15 +4936,15 @@ int fd_inc_sndbuf(int fd, size_t n) { socklen_t l = sizeof(value); r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l); - if (r >= 0 && - l == sizeof(value) && - (size_t) value >= n*2) + if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2) return 0; + /* If we have the privileges we will ignore the kernel limit. */ + value = (int) n; - r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)); - if (r < 0) - return -errno; + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0) + return -errno; return 1; } @@ -4954,16 +4954,15 @@ int fd_inc_rcvbuf(int fd, size_t n) { socklen_t l = sizeof(value); r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l); - if (r >= 0 && - l == sizeof(value) && - (size_t) value >= n*2) + if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2) return 0; - value = (int) n; - r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)); - if (r < 0) - return -errno; + /* If we have the privileges we will ignore the kernel limit. */ + value = (int) n; + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0) + return -errno; return 1; } @@ -5155,7 +5154,7 @@ bool is_valid_documentation_url(const char *url) { } bool in_initrd(void) { - static __thread int saved = -1; + static int saved = -1; struct statfs s; if (saved >= 0) @@ -5220,10 +5219,10 @@ int make_console_stdio(void) { } int get_home_dir(char **_h) { - char *h; + struct passwd *p; const char *e; + char *h; uid_t u; - struct passwd *p; assert(_h); @@ -5266,6 +5265,53 @@ int get_home_dir(char **_h) { return 0; } +int get_shell(char **_s) { + struct passwd *p; + const char *e; + char *s; + uid_t u; + + assert(_s); + + /* Take the user specified one */ + e = getenv("SHELL"); + if (e) { + s = strdup(e); + if (!s) + return -ENOMEM; + + *_s = s; + return 0; + } + + /* Hardcode home directory for root to avoid NSS */ + u = getuid(); + if (u == 0) { + s = strdup("/bin/sh"); + if (!s) + return -ENOMEM; + + *_s = s; + return 0; + } + + /* Check the database... */ + errno = 0; + p = getpwuid(u); + if (!p) + return errno > 0 ? -errno : -ESRCH; + + if (!path_is_absolute(p->pw_shell)) + return -EINVAL; + + s = strdup(p->pw_shell); + if (!s) + return -ENOMEM; + + *_s = s; + return 0; +} + bool filename_is_safe(const char *p) { if (isempty(p)) @@ -5983,18 +6029,24 @@ int container_get_leader(const char *machine, pid_t *pid) { return 0; } -int namespace_open(pid_t pid, int *namespace_fd, int *root_fd) { - _cleanup_close_ int nsfd = -1; - const char *ns, *root; +int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *root_fd) { + _cleanup_close_ int pidnsfd = -1, mntnsfd = -1; + const char *pidns, *mntns, *root; int rfd; assert(pid >= 0); - assert(namespace_fd); + assert(pidns_fd); + assert(mntns_fd); assert(root_fd); - ns = procfs_file_alloca(pid, "ns/mnt"); - nsfd = open(ns, O_RDONLY|O_NOCTTY|O_CLOEXEC); - if (nsfd < 0) + mntns = procfs_file_alloca(pid, "ns/mnt"); + mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC); + if (mntnsfd < 0) + return -errno; + + pidns = procfs_file_alloca(pid, "ns/pid"); + pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC); + if (pidnsfd < 0) return -errno; root = procfs_file_alloca(pid, "root"); @@ -6002,18 +6054,24 @@ int namespace_open(pid_t pid, int *namespace_fd, int *root_fd) { if (rfd < 0) return -errno; - *namespace_fd = nsfd; + *pidns_fd = pidnsfd; + *mntns_fd = mntnsfd; *root_fd = rfd; - nsfd = -1; + pidnsfd = -1; + mntnsfd = -1; return 0; } -int namespace_enter(int namespace_fd, int root_fd) { - assert(namespace_fd >= 0); +int namespace_enter(int pidns_fd, int mntns_fd, int root_fd) { + assert(pidns_fd >= 0); + assert(mntns_fd >= 0); assert(root_fd >= 0); - if (setns(namespace_fd, CLONE_NEWNS) < 0) + if (setns(pidns_fd, CLONE_NEWPID) < 0) + return -errno; + + if (setns(mntns_fd, CLONE_NEWNS) < 0) return -errno; if (fchdir(root_fd) < 0)