run_as: add extract ELF symbol offset command
authorFrancis Deslauriers <francis.deslauriers@efficios.com>
Thu, 28 Jun 2018 16:38:46 +0000 (12:38 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 24 Aug 2018 19:57:18 +0000 (15:57 -0400)
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 <francis.deslauriers@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
configure.ac
src/common/Makefile.am
src/common/runas-stub.c [new file with mode: 0644]
src/common/runas.c
src/common/runas.h

index d8625fc21ede93a5b5a2f56cef0eb20044dd4285..fb2a31f9bdf7bffc360d4862061e3790283a0047 100644 (file)
@@ -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])
index 171748f433aacc32cc3f79254e1cb1ea4e1957ec..d6a7da1d8b790fefbbfc95d60ab16b2e5fc94b82 100644 (file)
@@ -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 (file)
index 0000000..99b44d3
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef _RUNAS_STUB_H
+#define _RUNAS_STUB_H
+
+/*
+ * Copyright (C) 2018 - Francis Deslauriers <francis.deslauriers@efficios.com>
+ *
+ * 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 <sys/types.h>
+#include <stdint.h>
+
+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 */
index 863e824283fccfb159fad9150d859317e596618d..bed25a46368d61d875939acd1461e0b98a3af4cb 100644 (file)
@@ -38,6 +38,9 @@
 #include <common/compat/prctl.h>
 #include <common/unix.h>
 #include <common/defaults.h>
+#include <common/lttng-elf.h>
+
+#include <lttng/constant.h>
 
 #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)
 {
index 46d4502e9c781a387f4723123f634167fe2a11ff..098d5c3aa41143440759f043ad41dd0978911895 100644 (file)
@@ -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
This page took 0.045169 seconds and 5 git commands to generate.