From 3b9b58b71775260422c9e700378aae0ce40711ac Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Thu, 16 Feb 2023 10:14:58 -0800 Subject: [PATCH] unix: Faccess: check CAP_DAC_OVERRIDE on Linux CL 126516 added support for flags argument, implemented in the same way as glibc does (it tries to guess what the kernel would do). CL 246537 added using faccess2(2) Linux syscall which supports the flags directly. For older kernels, though, the syscall is not available, and the code uses glibc-like fallback. There is one very specific scenario in which the fallback fails. The scenario involves all these conditions: - no faccessat2 support available (i.e. either Linux kernel < 5.8, or a seccomp set up to disable faccessat2); - the current user is not root (i.e. geteuid() != 0); - CAP_DAC_OVERRIDE capability is set for the current process; - the file to be executed does not have executable permission bit set for either the current EUID or EGID; - the file to be executed have at least one executable bit set. Unfortunately, this set of conditions was observed in the wild -- a container run as a non-root user with the binary file owned by root with executable permission set for a user only [1]. Essentially it means it is not as rare as it may seem. Now, CAP_DAC_OVERRIDE essentially makes the kernel bypass most of the checks, so execve(2) and friends work the same was as for root user, i.e. if at least one executable bit it set, the permission to execute is granted (see generic_permission() function in the Linux kernel). Modify the code to check for CAP_DAC_OVERRIDE and mimic the kernel behavior for permission checks. This is essentially the same fix as CL 468735 for Go syscall package. Tested on CentOS 7 with the repro similar to the one from [2]. [1] https://github.com/opencontainers/runc/issues/3715 [2] https://github.com/golang/go/issues/58552#issuecomment-1432505621 Change-Id: I726b6acab6a6e6d0358ef98e6a582b405c347614 Signed-off-by: Kir Kolyshkin Reviewed-on: https://go-review.googlesource.com/c/sys/+/468877 Reviewed-by: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Gopher Robot Reviewed-by: Bryan Mills Auto-Submit: Ian Lance Taylor --- unix/syscall_linux.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go index 5443dddd..573d0610 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go @@ -2154,6 +2154,14 @@ func isGroupMember(gid int) bool { return false } +func isCapDacOverrideSet() bool { + hdr := CapUserHeader{Version: LINUX_CAPABILITY_VERSION_3} + data := [2]CapUserData{} + err := Capget(&hdr, &data[0]) + + return err == nil && data[0].Effective&(1<