[PATCH RFC v3 65/90] capabilities: take nothing from a file in a cell

From: Josef Bacik

Date: Thu Nov 05 2026 - 10:36:47 EST


File capabilities with the effective bit set mark a program that does not
know about capabilities and relies on having them. If one of those
capabilities is missing from the bounding set, the program is not run at
all, and execve() fails with EPERM. This is why ping does not start in a
container that was created with --cap-drop=ALL.

The bounding set of a cell is what the builder named, which is nothing by
default. Every task of a cell also has no_new_privs, so whatever the file
offers is discarded later in the exec anyway. The only effect that reading
the file capabilities can have is to stop the program from running.

Do not read them for a task of a cell, as is already the case for a file
on a nosuid mount. The program runs and gains nothing, which is also what
happens with a set-uid bit in a cell.

Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
---
security/commoncap.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/security/commoncap.c b/security/commoncap.c
index 8af343c78d35..02e25ab18f56 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -777,6 +777,13 @@ static int get_file_caps(struct linux_binprm *bprm, const struct file *file,
if (!mnt_may_suid(file->f_path.mnt))
return 0;

+ /*
+ * A task of a cell gains nothing from a file, so do not look. A file that
+ * insists on a capability which is not in the bounding set would not run.
+ */
+ if (userns_is_cell(bprm->cred->user_ns))
+ return 0;
+
/*
* This check is redundant with mnt_may_suid() but is kept to make
* explicit that capability bits are limited to s_user_ns and its

--
2.55.0