From 3162b407020980f358c57af1888b4a83ec08c5b1 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Sun, 28 Jan 2018 21:30:19 -0800 Subject: [PATCH] daemon: add API to get kernel symbols This is useful because we might not have access to kernel symbols from user applications which are not root. Various distributions are starting to censor kernel addresses without root. This allows the clients to fetch the symbol addresses without having to be root themselves. --- daemon/meson.build | 9 +++- daemon/sysprofd.c | 90 ++++++++++++++++++++++++++----- data/org.gnome.Sysprof2.xml | 15 ++++++ data/org.gnome.sysprof2.policy.in | 12 +++++ 4 files changed, 113 insertions(+), 13 deletions(-) diff --git a/daemon/meson.build b/daemon/meson.build index 81f2484a..d0cf87cd 100644 --- a/daemon/meson.build +++ b/daemon/meson.build @@ -4,16 +4,23 @@ sysprofd_sources = [ 'sysprofd.c', 'sd-bus-helper.c', 'sd-bus-helper.h', + '../lib/sp-kallsyms.c', + '../lib/sp-kallsyms.h', ] # NOTE: This is used in data/meson.build pkglibexecdir = join_paths(get_option('prefix'), get_option('libexecdir'), 'sysprof') +sysprofd_deps = [ + dependency('libsystemd', version: '>=222'), + dependency('glib-2.0'), +] + sysprofd = executable('sysprofd', sysprofd_sources, c_args: exe_c_args, link_args: exe_link_args, - dependencies: dependency('libsystemd', version: '>=222'), + dependencies: sysprofd_deps, install: true, install_dir: pkglibexecdir, ) diff --git a/daemon/sysprofd.c b/daemon/sysprofd.c index 681cd63b..8544ffec 100644 --- a/daemon/sysprofd.c +++ b/daemon/sysprofd.c @@ -16,13 +16,12 @@ * along with this program. If not, see . */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "config.h" #include #include #include +#include #include #include #include @@ -31,9 +30,84 @@ #include #include "sd-bus-helper.h" +#include "../lib/sp-kallsyms.h" #define BUS_TIMEOUT_USEC (1000000L * 10L) +#if 0 +#define GOTO(l) do { \ + fprintf (stderr, "GOTO: %s:%d: " #l "\n", __FUNCTION__, __LINE__); \ + goto l; \ +} while (0) +#else +#define GOTO(l) goto l +#endif + +static int +sysprofd_get_kernel_symbols (sd_bus_message *msg, + void *user_data, + sd_bus_error *error) +{ + g_autoptr(SpKallsyms) kallsyms = NULL; + sd_bus_message *reply = NULL; + const gchar *name; + guint64 addr; + guint8 type; + bool challenge = false; + int r; + + assert (msg); + assert (error); + + /* Authorize peer */ + r = bus_test_polkit (msg, + CAP_SYS_ADMIN, + "org.gnome.sysprof2.get-kernel-symbols", + NULL, + UID_INVALID, + &challenge, + error); + + if (r <= 0) + fprintf (stderr, "GetKernelSymbols() Failure: %s\n", error->message); + + if (r < 0) + return r; + else if (r == 0) + return -EACCES; + + if (!(kallsyms = sp_kallsyms_new ())) + { + sd_bus_error_set (error, + SD_BUS_ERROR_FILE_NOT_FOUND, + "Failed to open /proc/kallsyms"); + return -ENOENT; + } + + r = sd_bus_message_new_method_return (msg, &reply); + if (r < 0) + return r; + + r = sd_bus_message_open_container (reply, 'a', "(tys)"); + if (r < 0) + return r; + + while (sp_kallsyms_next (kallsyms, &name, &addr, &type)) + { + g_print ("%s: %lu\n", name, addr); + sd_bus_message_append (reply, "(tys)", addr, type, name); + } + + r = sd_bus_message_close_container (reply); + if (r < 0) + return r; + + r = sd_bus_send (NULL, reply, NULL); + sd_bus_message_unref (reply); + + return r; +} + static int _perf_event_open (struct perf_event_attr *attr, pid_t pid, @@ -50,15 +124,6 @@ _perf_event_open (struct perf_event_attr *attr, return syscall (__NR_perf_event_open, attr, pid, cpu, group_fd, flags); } -#if 0 -#define GOTO(l) do { \ - fprintf (stderr, "GOTO: %s:%d: " #l "\n", __FUNCTION__, __LINE__); \ - goto l; \ -} while (0) -#else -#define GOTO(l) goto l -#endif - static int sysprofd_perf_event_open (sd_bus_message *msg, void *user_data, @@ -274,6 +339,7 @@ sysprofd_perf_event_open (sd_bus_message *msg, static const sd_bus_vtable sysprofd_vtable[] = { SD_BUS_VTABLE_START (0), SD_BUS_METHOD ("PerfEventOpen", "a{sv}iit", "h", sysprofd_perf_event_open, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD ("GetKernelSymbols", "", "a(tys)", sysprofd_get_kernel_symbols, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_END }; diff --git a/data/org.gnome.Sysprof2.xml b/data/org.gnome.Sysprof2.xml index 46e87e12..b22de4fa 100644 --- a/data/org.gnome.Sysprof2.xml +++ b/data/org.gnome.Sysprof2.xml @@ -20,5 +20,20 @@ + + + + + diff --git a/data/org.gnome.sysprof2.policy.in b/data/org.gnome.sysprof2.policy.in index 5ba36e11..7398a163 100644 --- a/data/org.gnome.sysprof2.policy.in +++ b/data/org.gnome.sysprof2.policy.in @@ -17,6 +17,18 @@ auth_admin_keep auth_admin_keep + org.gnome.sysprof2.get-kernel-symbols + + + + Get a list of kernel symbols and their address + Authentication is required to access Linux kernel information. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + org.gnome.sysprof2.perf-event-open