X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Frunas.c;h=d75eb21027ce0ae2b7df768698d8c913bb4297ea;hp=4742a792eca105f35f1a8e2d194db9aeecd55a66;hb=3fd15a7429ca3f5307a783e264155ae0218511ec;hpb=1af0e2e4d4a770e32f4fc169122b0c338bd799f6 diff --git a/src/common/runas.c b/src/common/runas.c index 4742a792e..d75eb2102 100644 --- a/src/common/runas.c +++ b/src/common/runas.c @@ -2,18 +2,18 @@ * Copyright (C) 2011 - David Goulet * Mathieu Desnoyers * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; only version 2 of the License. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, version 2 only, + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307, USA. + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _GNU_SOURCE @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -38,6 +39,10 @@ #define RUNAS_CHILD_STACK_SIZE 10485760 +#ifndef MAP_STACK +#define MAP_STACK 0 +#endif + #ifdef __FreeBSD__ /* FreeBSD MAP_STACK always return -ENOMEM */ #define LTTNG_MAP_STACK 0 @@ -80,56 +85,12 @@ int _mkdir_recursive(void *_data) { struct run_as_mkdir_data *data = _data; const char *path; - char *p, tmp[PATH_MAX]; - struct stat statbuf; mode_t mode; - size_t len; - int ret; path = data->path; mode = data->mode; - ret = snprintf(tmp, sizeof(tmp), "%s", path); - if (ret < 0) { - PERROR("snprintf mkdir"); - goto error; - } - - len = ret; - if (tmp[len - 1] == '/') { - tmp[len - 1] = 0; - } - - for (p = tmp + 1; *p; p++) { - if (*p == '/') { - *p = 0; - ret = stat(tmp, &statbuf); - if (ret < 0) { - ret = mkdir(tmp, mode); - if (ret < 0) { - if (!(errno == EEXIST)) { - PERROR("mkdir recursive"); - ret = -errno; - goto error; - } - } - } - *p = '/'; - } - } - - ret = mkdir(tmp, mode); - if (ret < 0) { - if (!(errno == EEXIST)) { - PERROR("mkdir recursive last piece"); - ret = -errno; - } else { - ret = 0; - } - } - -error: - return ret; + return utils_mkdir_recursive(path, mode); } static @@ -149,13 +110,14 @@ int _open(void *_data) static int child_run_as(void *_data) { + int ret; struct run_as_data *data = _data; - size_t writelen, writeleft, index; + ssize_t writelen; + size_t writeleft, index; union { int i; char c[sizeof(int)]; } sendret; - int ret; /* * Child: it is safe to drop egid and euid while sharing the @@ -167,14 +129,14 @@ int child_run_as(void *_data) if (data->gid != getegid()) { ret = setegid(data->gid); if (ret < 0) { - perror("setegid"); + PERROR("setegid"); return EXIT_FAILURE; } } if (data->uid != geteuid()) { ret = seteuid(data->uid); if (ret < 0) { - perror("seteuid"); + PERROR("seteuid"); return EXIT_FAILURE; } } @@ -187,10 +149,12 @@ int child_run_as(void *_data) writeleft = sizeof(sendret); index = 0; do { - writelen = write(data->retval_pipe, &sendret.c[index], - writeleft); + do { + writelen = write(data->retval_pipe, &sendret.c[index], + writeleft); + } while (writelen < 0 && errno == EINTR); if (writelen < 0) { - perror("write"); + PERROR("write"); return EXIT_FAILURE; } writeleft -= writelen; @@ -227,7 +191,7 @@ int run_as_clone(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) ret = pipe(retval_pipe); if (ret < 0) { - perror("pipe"); + PERROR("pipe"); retval.i = ret; goto end; } @@ -241,7 +205,7 @@ int run_as_clone(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) MAP_PRIVATE | MAP_GROWSDOWN | MAP_ANONYMOUS | LTTNG_MAP_STACK, -1, 0); if (child_stack == MAP_FAILED) { - perror("mmap"); + PERROR("mmap"); retval.i = -ENOMEM; goto close_pipe; } @@ -252,7 +216,7 @@ int run_as_clone(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) pid = lttng_clone_files(child_run_as, child_stack + (RUNAS_CHILD_STACK_SIZE / 2), &run_as_data); if (pid < 0) { - perror("clone"); + PERROR("clone"); retval.i = pid; goto unmap_stack; } @@ -262,7 +226,7 @@ int run_as_clone(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) do { readlen = read(retval_pipe[0], &retval.c[index], readleft); if (readlen < 0) { - perror("read"); + PERROR("read"); ret = -1; break; } @@ -276,18 +240,24 @@ int run_as_clone(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) */ pid = waitpid(pid, &status, 0); if (pid < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { - perror("wait"); + PERROR("wait"); retval.i = -1; } unmap_stack: ret = munmap(child_stack, RUNAS_CHILD_STACK_SIZE); if (ret < 0) { - perror("munmap"); + PERROR("munmap"); retval.i = ret; } close_pipe: - close(retval_pipe[0]); - close(retval_pipe[1]); + ret = close(retval_pipe[0]); + if (ret) { + PERROR("close"); + } + ret = close(retval_pipe[1]); + if (ret) { + PERROR("close"); + } end: return retval.i; } @@ -300,21 +270,34 @@ end: static int run_as_noclone(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) { - return cmd(data); + int ret; + mode_t old_mask; + + old_mask = umask(0); + ret = cmd(data); + umask(old_mask); + + return ret; } static int run_as(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) { if (!getenv("LTTNG_DEBUG_NOCLONE")) { + int ret; + DBG("Using run_as_clone"); - return run_as_clone(cmd, data, uid, gid); + pthread_mutex_lock(<tng_libc_state_lock); + ret = run_as_clone(cmd, data, uid, gid); + pthread_mutex_unlock(<tng_libc_state_lock); + return ret; } else { DBG("Using run_as_noclone"); return run_as_noclone(cmd, data, uid, gid); } } +__attribute__((visibility("hidden"))) int run_as_mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid) { struct run_as_mkdir_data data; @@ -326,6 +309,7 @@ int run_as_mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid) return run_as(_mkdir_recursive, &data, uid, gid); } +__attribute__((visibility("hidden"))) int run_as_mkdir(const char *path, mode_t mode, uid_t uid, gid_t gid) { struct run_as_mkdir_data data; @@ -341,6 +325,7 @@ int run_as_mkdir(const char *path, mode_t mode, uid_t uid, gid_t gid) * Note: open_run_as is currently not working. We'd need to pass the fd * opened in the child to the parent. */ +__attribute__((visibility("hidden"))) int run_as_open(const char *path, int flags, mode_t mode, uid_t uid, gid_t gid) { struct run_as_open_data data;