X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Fcommon%2Frunas.c;h=4742a792eca105f35f1a8e2d194db9aeecd55a66;hb=2d85a600590b23ca5ca1e182187d08f44808ef80;hp=86db9b8682c343efaee59a08bee72123fc518d60;hpb=89831a7431103178268b5f1dccbf094e7c4f4095;p=lttng-tools.git diff --git a/src/common/runas.c b/src/common/runas.c index 86db9b868..4742a792e 100644 --- a/src/common/runas.c +++ b/src/common/runas.c @@ -38,8 +38,19 @@ #define RUNAS_CHILD_STACK_SIZE 10485760 -#ifndef MAP_STACK -#define MAP_STACK 0 +#ifdef __FreeBSD__ +/* FreeBSD MAP_STACK always return -ENOMEM */ +#define LTTNG_MAP_STACK 0 +#else +#define LTTNG_MAP_STACK MAP_STACK +#endif + +#ifndef MAP_GROWSDOWN +#define MAP_GROWSDOWN 0 +#endif + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON #endif struct run_as_data { @@ -189,7 +200,7 @@ int child_run_as(void *_data) } static -int run_as(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) +int run_as_clone(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) { struct run_as_data run_as_data; int ret = 0; @@ -217,6 +228,7 @@ int run_as(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) ret = pipe(retval_pipe); if (ret < 0) { perror("pipe"); + retval.i = ret; goto end; } run_as_data.data = data; @@ -226,11 +238,11 @@ int run_as(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) run_as_data.retval_pipe = retval_pipe[1]; /* write end */ child_stack = mmap(NULL, RUNAS_CHILD_STACK_SIZE, PROT_WRITE | PROT_READ, - MAP_PRIVATE | MAP_GROWSDOWN | MAP_ANONYMOUS | MAP_STACK, + MAP_PRIVATE | MAP_GROWSDOWN | MAP_ANONYMOUS | LTTNG_MAP_STACK, -1, 0); if (child_stack == MAP_FAILED) { perror("mmap"); - ret = -ENOMEM; + retval.i = -ENOMEM; goto close_pipe; } /* @@ -241,7 +253,7 @@ int run_as(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) &run_as_data); if (pid < 0) { perror("clone"); - ret = pid; + retval.i = pid; goto unmap_stack; } /* receive return value */ @@ -265,12 +277,13 @@ int run_as(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"); - ret = -1; + retval.i = -1; } unmap_stack: ret = munmap(child_stack, RUNAS_CHILD_STACK_SIZE); if (ret < 0) { perror("munmap"); + retval.i = ret; } close_pipe: close(retval_pipe[0]); @@ -279,6 +292,29 @@ end: return retval.i; } +/* + * To be used on setups where gdb has issues debugging programs using + * clone/rfork. Note that this is for debuging ONLY, and should not be + * considered secure. + */ +static +int run_as_noclone(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) +{ + return cmd(data); +} + +static +int run_as(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid) +{ + if (!getenv("LTTNG_DEBUG_NOCLONE")) { + DBG("Using run_as_clone"); + return run_as_clone(cmd, data, uid, gid); + } else { + DBG("Using run_as_noclone"); + return run_as_noclone(cmd, data, uid, gid); + } +} + int run_as_mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid) { struct run_as_mkdir_data data;