From 11870d714a1b744a0225e90b0b395346357defe9 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Sun, 29 May 2016 00:15:13 +0900 Subject: [PATCH] perf symbols: Introduce filename__readable to check readability Introduce filename__readable to check readability by opening the file directly. Since the access(R_OK) just checks the readability based on real UID/GID, it is ignored that the effective UID/GID and capabilities for some special file (e.g. /proc/kcore). filename__readable() directly opens given file with O_RDONLY so that the kernel checks it by effective UID/GID and capabilities. Signed-off-by: Masami Hiramatsu Acked-by: Namhyung Kim Cc: Ananth N Mavinakayanahalli Cc: Brendan Gregg Cc: Hemant Kumar Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20160528151513.16098.97576.stgit@devbox Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 54c4ff2b1cee..a469346a305d 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1641,6 +1641,20 @@ static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz) return ret; } +/* + * Use open(O_RDONLY) to check readability directly instead of access(R_OK) + * since access(R_OK) only checks with real UID/GID but open() use effective + * UID/GID and actual capabilities (e.g. /proc/kcore requires CAP_SYS_RAWIO). + */ +static bool filename__readable(const char *file) +{ + int fd = open(file, O_RDONLY); + if (fd < 0) + return false; + close(fd); + return true; +} + static char *dso__find_kallsyms(struct dso *dso, struct map *map) { u8 host_build_id[BUILD_ID_SIZE]; @@ -1668,7 +1682,6 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map) /* Use /proc/kallsyms if possible */ if (is_host) { DIR *d; - int fd; /* If no cached kcore go with /proc/kallsyms */ d = opendir(path); @@ -1677,16 +1690,15 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map) closedir(d); /* - * Do not check the build-id cache, until we know we cannot use - * /proc/kcore. + * Do not check the build-id cache, unless we know we cannot use + * /proc/kcore or module maps don't match to /proc/kallsyms. + * To check readability of /proc/kcore, do not use access(R_OK) + * since /proc/kcore requires CAP_SYS_RAWIO to read and access + * can't check it. */ - fd = open("/proc/kcore", O_RDONLY); - if (fd != -1) { - close(fd); - /* If module maps match go with /proc/kallsyms */ - if (!validate_kcore_addresses("/proc/kallsyms", map)) - goto proc_kallsyms; - } + if (filename__readable("/proc/kcore") && + !validate_kcore_addresses("/proc/kallsyms", map)) + goto proc_kallsyms; /* Find kallsyms in build-id cache with kcore */ if (!find_matching_kcore(map, path, sizeof(path)))