Re: [PATCH perf/core v9 01/16] perf-symbol: Introduce filename__readable to check readability

From: Arnaldo Carvalho de Melo
Date: Mon May 30 2016 - 12:03:26 EST


Em Sun, May 29, 2016 at 12:15:13AM +0900, Masami Hiramatsu escreveu:
> 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.


You missed the Signed-off-by line.

- Arnaldo

> ---
> 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 54c4ff2..a469346 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)))