Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libbpf: Fix the case of running as non-root with capabilities

When running rootless with special capabilities like:
FOWNER / DAC_OVERRIDE / DAC_READ_SEARCH

The "access" API will not make the proper check if there is really
access to a file or not.

>From the access man page:
"
The check is done using the calling process's real UID and GID, rather
than the effective IDs as is done when actually attempting an operation
(e.g., open(2)) on the file. Similarly, for the root user, the check
uses the set of permitted capabilities rather than the set of effective
capabilities; ***and for non-root users, the check uses an empty set of
capabilities.***
"

What that means is that for non-root user the access API will not do the
proper validation if the process really has permission to a file or not.

To resolve this this patch replaces all the access API calls with
faccessat with AT_EACCESS flag.

Signed-off-by: Jon Doron <jond@wiz.io>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20220925070431.1313680-1-arilou@gmail.com

authored by

Jon Doron and committed by
Andrii Nakryiko
6a4ab886 9666a702

+5 -5
+1 -1
tools/lib/bpf/btf.c
··· 4664 4664 for (i = 0; i < ARRAY_SIZE(locations); i++) { 4665 4665 snprintf(path, PATH_MAX, locations[i], buf.release); 4666 4666 4667 - if (access(path, R_OK)) 4667 + if (faccessat(AT_FDCWD, path, R_OK, AT_EACCESS)) 4668 4668 continue; 4669 4669 4670 4670 btf = btf__parse(path, NULL);
+3 -3
tools/lib/bpf/libbpf.c
··· 884 884 __u32 major, minor, patch; 885 885 struct utsname info; 886 886 887 - if (access(ubuntu_kver_file, R_OK) == 0) { 887 + if (faccessat(AT_FDCWD, ubuntu_kver_file, R_OK, AT_EACCESS) == 0) { 888 888 FILE *f; 889 889 890 890 f = fopen(ubuntu_kver_file, "r"); ··· 9904 9904 static int has_debugfs = -1; 9905 9905 9906 9906 if (has_debugfs < 0) 9907 - has_debugfs = access(DEBUGFS, F_OK) == 0; 9907 + has_debugfs = faccessat(AT_FDCWD, DEBUGFS, F_OK, AT_EACCESS) == 0; 9908 9908 9909 9909 return has_debugfs == 1; 9910 9910 } ··· 10721 10721 continue; 10722 10722 snprintf(result, result_sz, "%.*s/%s", seg_len, s, file); 10723 10723 /* ensure it has required permissions */ 10724 - if (access(result, perm) < 0) 10724 + if (faccessat(AT_FDCWD, result, perm, AT_EACCESS) < 0) 10725 10725 continue; 10726 10726 pr_debug("resolved '%s' to '%s'\n", file, result); 10727 10727 return 0;
+1 -1
tools/lib/bpf/usdt.c
··· 282 282 * If this is not supported, USDTs with semaphores will not be supported. 283 283 * Added in: a6ca88b241d5 ("trace_uprobe: support reference counter in fd-based uprobe") 284 284 */ 285 - man->has_sema_refcnt = access(ref_ctr_sysfs_path, F_OK) == 0; 285 + man->has_sema_refcnt = faccessat(AT_FDCWD, ref_ctr_sysfs_path, F_OK, AT_EACCESS) == 0; 286 286 287 287 return man; 288 288 }