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