From: Francis Deslauriers Date: Thu, 28 Jun 2018 16:38:46 +0000 (-0400) Subject: run_as: add extract ELF symbol offset command X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=commitdiff_plain;h=241e0a5ac6da55b41adaf516fbd36af332d94b3d run_as: add extract ELF symbol offset command We use a run_as command for this work because the input is controlled by the user and it should be parsed using the permission of that user. Also, parsing ELF files is tricky and doing it in a run_as process has the benefit of isolating potential crashes. Signed-off-by: Francis Deslauriers Signed-off-by: Jérémie Galarneau --- diff --git a/configure.ac b/configure.ac index d8625fc21..fb2a31f9b 100644 --- a/configure.ac +++ b/configure.ac @@ -867,6 +867,7 @@ build_lib_compat=no build_lib_consumer=no build_lib_hashtable=no build_lib_health=no +build_lib_runas=no build_lib_unix=no build_lib_index=no build_lib_kernel_consumer=no @@ -924,6 +925,7 @@ AS_IF([test x$enable_bin_lttng_sessiond != xno], build_lib_relayd=yes build_lib_testpoint=yes build_lib_health=yes + build_lib_runas=yes build_lib_unix=yes ] ) @@ -1033,6 +1035,7 @@ AM_CONDITIONAL([BUILD_LIB_CONFIG], [test x$build_lib_config = xyes]) AM_CONDITIONAL([BUILD_LIB_CONSUMER], [test x$build_lib_consumer = xyes]) AM_CONDITIONAL([BUILD_LIB_HASHTABLE], [test x$build_lib_hashtable = xyes]) AM_CONDITIONAL([BUILD_LIB_HEALTH], [test x$build_lib_health = xyes]) +AM_CONDITIONAL([BUILD_LIB_RUNAS], [test x$build_lib_runas = xyes]) AM_CONDITIONAL([BUILD_LIB_UNIX], [test x$build_lib_unix = xyes]) AM_CONDITIONAL([BUILD_LIB_INDEX], [test x$build_lib_index = xyes]) AM_CONDITIONAL([BUILD_LIB_KERNEL_CONSUMER], [test x$build_lib_kernel_consumer = xyes]) diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 171748f43..d6a7da1d8 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -12,7 +12,7 @@ DIST_SUBDIRS = compat health hashtable kernel-ctl sessiond-comm relayd \ noinst_LTLIBRARIES = libcommon.la EXTRA_DIST = mi-lttng-3.0.xsd -libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.h runas.c \ +libcommon_la_SOURCES = error.h error.c utils.c utils.h runas.h \ common.h futex.c futex.h uri.c uri.h defaults.c \ pipe.c pipe.h readwrite.c readwrite.h \ mi-lttng.h mi-lttng.c \ @@ -33,6 +33,12 @@ libcommon_la_LIBADD = \ $(top_builddir)/src/common/config/libconfig.la \ $(UUID_LIBS) +if BUILD_LIB_RUNAS +libcommon_la_SOURCES += runas.c lttng-elf.h lttng-elf.c +else +libcommon_la_SOURCES += runas-stub.c +endif + if BUILD_LIB_UNIX libcommon_la_SOURCES += unix.c else diff --git a/src/common/runas-stub.c b/src/common/runas-stub.c new file mode 100644 index 000000000..99b44d32a --- /dev/null +++ b/src/common/runas-stub.c @@ -0,0 +1,57 @@ +#ifndef _RUNAS_STUB_H +#define _RUNAS_STUB_H + +/* + * Copyright (C) 2018 - Francis Deslauriers + * + * 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 + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +int run_as_mkdir_recursive(const char *path, mode_t mode, uid_t uid, gid_t gid) +{ + return -1; +} +int run_as_mkdir(const char *path, mode_t mode, uid_t uid, gid_t gid) +{ + return -1; +} +int run_as_open(const char *path, int flags, mode_t mode, uid_t uid, gid_t gid) +{ + return -1; +} +int run_as_unlink(const char *path, uid_t uid, gid_t gid) +{ + return -1; +} +int run_as_rmdir_recursive(const char *path, uid_t uid, gid_t gid) +{ + return -1; +} +int lttng_elf_get_symbol_offset(int fd, char *symbol, uint64_t *offset) +{ + return -1; +} +int run_as_create_worker(char *procname) +{ + return -1; +} +void run_as_destroy_worker(void) +{ + return; +} + +#endif /* _RUNAS_STUB_H */ diff --git a/src/common/runas.c b/src/common/runas.c index 863e82428..bed25a463 100644 --- a/src/common/runas.c +++ b/src/common/runas.c @@ -38,6 +38,9 @@ #include #include #include +#include + +#include #include "runas.h" @@ -64,6 +67,10 @@ struct run_as_rmdir_recursive_data { char path[PATH_MAX]; }; +struct run_as_extract_elf_symbol_offset_data { + char function[LTTNG_SYMBOL_NAME_LEN]; +}; + struct run_as_mkdir_ret { int ret; }; @@ -80,12 +87,17 @@ struct run_as_rmdir_recursive_ret { int ret; }; +struct run_as_extract_elf_symbol_offset_ret { + uint64_t offset; +}; + enum run_as_cmd { RUN_AS_MKDIR, RUN_AS_OPEN, RUN_AS_UNLINK, RUN_AS_RMDIR_RECURSIVE, RUN_AS_MKDIR_RECURSIVE, + RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET, }; struct run_as_data { @@ -96,6 +108,7 @@ struct run_as_data { struct run_as_open_data open; struct run_as_unlink_data unlink; struct run_as_rmdir_recursive_data rmdir_recursive; + struct run_as_extract_elf_symbol_offset_data extract_elf_symbol_offset; } u; uid_t uid; gid_t gid; @@ -123,6 +136,7 @@ struct run_as_ret { struct run_as_open_ret open; struct run_as_unlink_ret unlink; struct run_as_rmdir_recursive_ret rmdir_recursive; + struct run_as_extract_elf_symbol_offset_ret extract_elf_symbol_offset; } u; int _errno; bool _error; @@ -212,6 +226,25 @@ int _rmdir_recursive(struct run_as_data *data, struct run_as_ret *ret_value) return ret_value->u.rmdir_recursive.ret; } +static +int _extract_elf_symbol_offset(struct run_as_data *data, + struct run_as_ret *ret_value) +{ + int ret = 0; + ret_value->_error = false; + + ret = lttng_elf_get_symbol_offset(data->fd, + data->u.extract_elf_symbol_offset.function, + &ret_value->u.extract_elf_symbol_offset.offset); + if (ret) { + DBG("Failed to extract ELF function offset"); + ret_value->_error = true; + } + + return ret; +} + + static run_as_fct run_as_enum_to_fct(enum run_as_cmd cmd) { @@ -226,6 +259,8 @@ run_as_fct run_as_enum_to_fct(enum run_as_cmd cmd) return _rmdir_recursive; case RUN_AS_MKDIR_RECURSIVE: return _mkdir_recursive; + case RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET: + return _extract_elf_symbol_offset; default: ERR("Unknown command %d", (int) cmd); return NULL; @@ -277,6 +312,8 @@ int send_fd_to_worker(struct run_as_worker *worker, enum run_as_cmd cmd, int fd) int ret = 0; switch (cmd) { + case RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET: + break; default: return 0; } @@ -343,6 +380,8 @@ int recv_fd_from_master(struct run_as_worker *worker, enum run_as_cmd cmd, int * int ret = 0; switch (cmd) { + case RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET: + break; default: return 0; } @@ -362,6 +401,8 @@ int cleanup_received_fd(enum run_as_cmd cmd, int fd) int ret = 0; switch (cmd) { + case RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET: + break; default: return 0; } @@ -806,6 +847,34 @@ int run_as_rmdir_recursive(const char *path, uid_t uid, gid_t gid) return ret.u.rmdir_recursive.ret; } +LTTNG_HIDDEN +int run_as_extract_elf_symbol_offset(int fd, const char* function, + uid_t uid, gid_t gid, uint64_t *offset) +{ + struct run_as_data data; + struct run_as_ret ret; + + DBG3("extract_elf_symbol_offset() on fd=%d and function=%s " + "with for uid %d and gid %d", fd, function, (int) uid, (int) gid); + + data.fd = fd; + + strncpy(data.u.extract_elf_symbol_offset.function, function, LTTNG_SYMBOL_NAME_LEN - 1); + + data.u.extract_elf_symbol_offset.function[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; + + run_as(RUN_AS_EXTRACT_ELF_SYMBOL_OFFSET, &data, &ret, uid, gid); + + errno = ret._errno; + + if (ret._error) { + return -1; + } + + *offset = ret.u.extract_elf_symbol_offset.offset; + return 0; +} + static int reset_sighandler(void) { diff --git a/src/common/runas.h b/src/common/runas.h index 46d4502e9..098d5c3aa 100644 --- a/src/common/runas.h +++ b/src/common/runas.h @@ -33,7 +33,9 @@ LTTNG_HIDDEN int run_as_unlink(const char *path, uid_t uid, gid_t gid); LTTNG_HIDDEN int run_as_rmdir_recursive(const char *path, uid_t uid, gid_t gid); - +LTTNG_HIDDEN +int run_as_extract_elf_symbol_offset(int fd, const char* function, + uid_t uid, gid_t gid, uint64_t *offset); LTTNG_HIDDEN int run_as_create_worker(char *procname); LTTNG_HIDDEN