|
@@ -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)))
|