Hi.
First, I hope you are fine and the same for your relatives.
Capabilities are used to check if a thread has the right to perform a given
action [1].
For example, a thread with CAP_BPF set can use the bpf() syscall.
Capabilities are used in the container world.
In terms of code, several projects related to container maintain code where the
capabilities are written alike include/uapi/linux/capability.h [2][3][4][5].
For these projects, their codebase should be updated when a new capability is
added to the kernel.
Some other projects rely on <sys/capability.h> [6].
In this case, this header file should reflect the capabilities offered by the
kernel.
So, in this series, I added a new file to sysfs: /sys/kernel/capabilities.
The goal of this file is to be used by "container world" software to know kernel
capabilities at run time instead of compile time.
The underlying kernel attribute is read-only and its content is the capability
number associated with the capability name:
root@vm-amd64:~# cat /sys/kernel/capabilities
0 CAP_CHOWN
1 CAP_DAC_OVERRIDE
...
39 CAP_BPF
The kernel already exposes the last capability number under:
/proc/sys/kernel/cap_last_cap
So, I think there should not be any issue exposing all the capabilities it
offers.
If there is any, please share it as I do not want to introduce issue with this
series.
Also, if you see any way to improve this series please share it as it would
increase this contribution quality.
Francis Laniel (2):
capability: Add cap_strings.
kernel/ksysfs.c: Add capabilities attribute.
include/uapi/linux/capability.h | 1 +
kernel/capability.c | 45 +++++++++++++++++++++++++++++++++
kernel/ksysfs.c | 18 +++++++++++++
3 files changed, 64 insertions(+)
Best regards and thank you in advance for your reviews.
---
[1] man capabilities
[2] https://github.com/containerd/containerd/blob/1a078e6893d07fec10a4940a5664fab21d6f7d1e/pkg/cap/cap_linux.go#L135
[3] https://github.com/moby/moby/commit/485cf38d48e7111b3d1f584d5e9eab46a902aabc#diff-2e04625b209932e74c617de96682ed72fbd1bb0d0cb9fb7c709cf47a86b6f9c1
moby relies on containerd code.
[4] https://github.com/syndtr/gocapability/blob/42c35b4376354fd554efc7ad35e0b7f94e3a0ffb/capability/enum.go#L47
[5] https://github.com/opencontainers/runc/blob/00f56786bb220b55b41748231880ba0e6380519a/libcontainer/capabilities/capabilities.go#L12
runc relies on syndtr package.
[6] https://github.com/containers/crun/blob/fafb556f09e6ffd4690c452ff51856b880c089f1/src/libcrun/linux.c#L35
--
2.30.2
This array contains the capability names for the given capabilitiy.
For example, index CAP_BPF contains "CAP_BPF".
Signed-off-by: Francis Laniel <[email protected]>
---
include/uapi/linux/capability.h | 1 +
kernel/capability.c | 45 +++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h
index 463d1ba2232a..9646654d5111 100644
--- a/include/uapi/linux/capability.h
+++ b/include/uapi/linux/capability.h
@@ -428,5 +428,6 @@ struct vfs_ns_cap_data {
#define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32 */
#define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed __u32 */
+extern const char *cap_strings[];
#endif /* _UAPI_LINUX_CAPABILITY_H */
diff --git a/kernel/capability.c b/kernel/capability.c
index 46a361dde042..5a2e71dcd87b 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -15,6 +15,7 @@
#include <linux/mm.h>
#include <linux/export.h>
#include <linux/security.h>
+#include <linux/stringify.h>
#include <linux/syscalls.h>
#include <linux/pid_namespace.h>
#include <linux/user_namespace.h>
@@ -27,6 +28,50 @@
const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET;
EXPORT_SYMBOL(__cap_empty_set);
+const char *cap_strings[] = {
+ [CAP_CHOWN] = __stringify_1(CAP_CHOWN),
+ [CAP_DAC_OVERRIDE] = __stringify_1(CAP_DAC_OVERRIDE),
+ [CAP_DAC_READ_SEARCH] = __stringify_1(CAP_DAC_READ_SEARCH),
+ [CAP_FOWNER] = __stringify_1(CAP_FOWNER),
+ [CAP_FSETID] = __stringify_1(CAP_FSETID),
+ [CAP_KILL] = __stringify_1(CAP_KILL),
+ [CAP_SETGID] = __stringify_1(CAP_SETGID),
+ [CAP_SETUID] = __stringify_1(CAP_SETUID),
+ [CAP_SETPCAP] = __stringify_1(CAP_SETPCAP),
+ [CAP_LINUX_IMMUTABLE] = __stringify_1(CAP_LINUX_IMMUTABLE),
+ [CAP_NET_BIND_SERVICE] = __stringify_1(CAP_NET_BIND_SERVICE),
+ [CAP_NET_BROADCAST] = __stringify_1(CAP_NET_BROADCAST),
+ [CAP_NET_ADMIN] = __stringify_1(CAP_NET_ADMIN),
+ [CAP_NET_RAW] = __stringify_1(CAP_NET_RAW),
+ [CAP_IPC_LOCK] = __stringify_1(CAP_IPC_LOCK),
+ [CAP_IPC_OWNER] = __stringify_1(CAP_IPC_OWNER),
+ [CAP_SYS_MODULE] = __stringify_1(CAP_SYS_MODULE),
+ [CAP_SYS_RAWIO] = __stringify_1(CAP_SYS_RAWIO),
+ [CAP_SYS_CHROOT] = __stringify_1(CAP_SYS_CHROOT),
+ [CAP_SYS_PTRACE] = __stringify_1(CAP_SYS_PTRACE),
+ [CAP_SYS_PACCT] = __stringify_1(CAP_SYS_PACCT),
+ [CAP_SYS_ADMIN] = __stringify_1(CAP_SYS_ADMIN),
+ [CAP_SYS_BOOT] = __stringify_1(CAP_SYS_BOOT),
+ [CAP_SYS_NICE] = __stringify_1(CAP_SYS_NICE),
+ [CAP_SYS_RESOURCE] = __stringify_1(CAP_SYS_RESOURCE),
+ [CAP_SYS_TIME] = __stringify_1(CAP_SYS_TIME),
+ [CAP_SYS_TTY_CONFIG] = __stringify_1(CAP_SYS_TTY_CONFIG),
+ [CAP_MKNOD] = __stringify_1(CAP_MKNOD),
+ [CAP_LEASE] = __stringify_1(CAP_LEASE),
+ [CAP_AUDIT_WRITE] = __stringify_1(CAP_AUDIT_WRITE),
+ [CAP_AUDIT_CONTROL] = __stringify_1(CAP_AUDIT_CONTROL),
+ [CAP_SETFCAP] = __stringify_1(CAP_SETFCAP),
+ [CAP_MAC_OVERRIDE] = __stringify_1(CAP_MAC_OVERRIDE),
+ [CAP_MAC_ADMIN] = __stringify_1(CAP_MAC_ADMIN),
+ [CAP_SYSLOG] = __stringify_1(CAP_SYSLOG),
+ [CAP_WAKE_ALARM] = __stringify_1(CAP_WAKE_ALARM),
+ [CAP_BLOCK_SUSPEND] = __stringify_1(CAP_BLOCK_SUSPEND),
+ [CAP_AUDIT_READ] = __stringify_1(CAP_AUDIT_READ),
+ [CAP_PERFMON] = __stringify_1(CAP_PERFMON),
+ [CAP_BPF] = __stringify_1(CAP_BPF),
+ [CAP_CHECKPOINT_RESTORE] = __stringify_1(CAP_CHECKPOINT_RESTORE),
+};
+
int file_caps_enabled = 1;
static int __init file_caps_disable(char *str)
--
2.30.2
This new read-only attribute prints the capabilities values with their names:
0 CAP_CHOWN
1 CAP_DAC_OVERRIDE
...
39 CAP_BPF
Signed-off-by: Francis Laniel <[email protected]>
---
kernel/ksysfs.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index 35859da8bd4f..7d39794a55bc 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -182,6 +182,23 @@ static ssize_t rcu_normal_store(struct kobject *kobj,
KERNEL_ATTR_RW(rcu_normal);
#endif /* #ifndef CONFIG_TINY_RCU */
+static ssize_t capabilities_show(struct kobject *unused0,
+ struct kobj_attribute *unused1, char *buf)
+{
+ int at = 0;
+ int i;
+
+ for (i = 0; i < CAP_LAST_CAP; i++) {
+ if (at >= PAGE_SIZE)
+ return at;
+
+ at += sysfs_emit_at(buf, at, "%d\t%s\n", i, cap_strings[i]);
+ }
+
+ return at;
+}
+KERNEL_ATTR_RO(capabilities);
+
/*
* Make /sys/kernel/notes give the raw contents of our kernel .notes section.
*/
@@ -229,6 +246,7 @@ static struct attribute * kernel_attrs[] = {
&rcu_expedited_attr.attr,
&rcu_normal_attr.attr,
#endif
+ &capabilities_attr.attr,
NULL
};
--
2.30.2
On 12/27/2021 12:54 PM, Francis Laniel wrote:
> Hi.
>
>
> First, I hope you are fine and the same for your relatives.
>
> Capabilities are used to check if a thread has the right to perform a given
> action [1].
> For example, a thread with CAP_BPF set can use the bpf() syscall.
>
> Capabilities are used in the container world.
> In terms of code, several projects related to container maintain code where the
> capabilities are written alike include/uapi/linux/capability.h [2][3][4][5].
> For these projects, their codebase should be updated when a new capability is
> added to the kernel.
> Some other projects rely on <sys/capability.h> [6].
> In this case, this header file should reflect the capabilities offered by the
> kernel.
>
> So, in this series, I added a new file to sysfs: /sys/kernel/capabilities.
This should be /sys/kernel/security/capabilities.
> The goal of this file is to be used by "container world" software to know kernel
> capabilities at run time instead of compile time.
>
> The underlying kernel attribute is read-only and its content is the capability
> number associated with the capability name:
> root@vm-amd64:~# cat /sys/kernel/capabilities
> 0 CAP_CHOWN
> 1 CAP_DAC_OVERRIDE
> ...
> 39 CAP_BPF
>
> The kernel already exposes the last capability number under:
> /proc/sys/kernel/cap_last_cap
> So, I think there should not be any issue exposing all the capabilities it
> offers.
> If there is any, please share it as I do not want to introduce issue with this
> series.
>
> Also, if you see any way to improve this series please share it as it would
> increase this contribution quality.
>
> Francis Laniel (2):
> capability: Add cap_strings.
> kernel/ksysfs.c: Add capabilities attribute.
>
> include/uapi/linux/capability.h | 1 +
> kernel/capability.c | 45 +++++++++++++++++++++++++++++++++
> kernel/ksysfs.c | 18 +++++++++++++
> 3 files changed, 64 insertions(+)
>
>
> Best regards and thank you in advance for your reviews.
> ---
> [1] man capabilities
> [2] https://github.com/containerd/containerd/blob/1a078e6893d07fec10a4940a5664fab21d6f7d1e/pkg/cap/cap_linux.go#L135
> [3] https://github.com/moby/moby/commit/485cf38d48e7111b3d1f584d5e9eab46a902aabc#diff-2e04625b209932e74c617de96682ed72fbd1bb0d0cb9fb7c709cf47a86b6f9c1
> moby relies on containerd code.
> [4] https://github.com/syndtr/gocapability/blob/42c35b4376354fd554efc7ad35e0b7f94e3a0ffb/capability/enum.go#L47
> [5] https://github.com/opencontainers/runc/blob/00f56786bb220b55b41748231880ba0e6380519a/libcontainer/capabilities/capabilities.go#L12
> runc relies on syndtr package.
> [6] https://github.com/containers/crun/blob/fafb556f09e6ffd4690c452ff51856b880c089f1/src/libcrun/linux.c#L35
>
On 12/27/2021 12:54 PM, Francis Laniel wrote:
> This array contains the capability names for the given capabilitiy.
> For example, index CAP_BPF contains "CAP_BPF".
>
> Signed-off-by: Francis Laniel <[email protected]>
> ---
> include/uapi/linux/capability.h | 1 +
> kernel/capability.c | 45 +++++++++++++++++++++++++++++++++
> 2 files changed, 46 insertions(+)
>
> diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h
> index 463d1ba2232a..9646654d5111 100644
> --- a/include/uapi/linux/capability.h
> +++ b/include/uapi/linux/capability.h
> @@ -428,5 +428,6 @@ struct vfs_ns_cap_data {
> #define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32 */
> #define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed __u32 */
>
> +extern const char *cap_strings[];
>
> #endif /* _UAPI_LINUX_CAPABILITY_H */
> diff --git a/kernel/capability.c b/kernel/capability.c
> index 46a361dde042..5a2e71dcd87b 100644
> --- a/kernel/capability.c
> +++ b/kernel/capability.c
> @@ -15,6 +15,7 @@
> #include <linux/mm.h>
> #include <linux/export.h>
> #include <linux/security.h>
> +#include <linux/stringify.h>
> #include <linux/syscalls.h>
> #include <linux/pid_namespace.h>
> #include <linux/user_namespace.h>
> @@ -27,6 +28,50 @@
> const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET;
> EXPORT_SYMBOL(__cap_empty_set);
>
> +const char *cap_strings[] = {
> + [CAP_CHOWN] = __stringify_1(CAP_CHOWN),
I may just be old and slow, but why is this better than
[CAP_CHOWN] = "CAP_CHOWN",
> + [CAP_DAC_OVERRIDE] = __stringify_1(CAP_DAC_OVERRIDE),
> + [CAP_DAC_READ_SEARCH] = __stringify_1(CAP_DAC_READ_SEARCH),
> + [CAP_FOWNER] = __stringify_1(CAP_FOWNER),
> + [CAP_FSETID] = __stringify_1(CAP_FSETID),
> + [CAP_KILL] = __stringify_1(CAP_KILL),
> + [CAP_SETGID] = __stringify_1(CAP_SETGID),
> + [CAP_SETUID] = __stringify_1(CAP_SETUID),
> + [CAP_SETPCAP] = __stringify_1(CAP_SETPCAP),
> + [CAP_LINUX_IMMUTABLE] = __stringify_1(CAP_LINUX_IMMUTABLE),
> + [CAP_NET_BIND_SERVICE] = __stringify_1(CAP_NET_BIND_SERVICE),
> + [CAP_NET_BROADCAST] = __stringify_1(CAP_NET_BROADCAST),
> + [CAP_NET_ADMIN] = __stringify_1(CAP_NET_ADMIN),
> + [CAP_NET_RAW] = __stringify_1(CAP_NET_RAW),
> + [CAP_IPC_LOCK] = __stringify_1(CAP_IPC_LOCK),
> + [CAP_IPC_OWNER] = __stringify_1(CAP_IPC_OWNER),
> + [CAP_SYS_MODULE] = __stringify_1(CAP_SYS_MODULE),
> + [CAP_SYS_RAWIO] = __stringify_1(CAP_SYS_RAWIO),
> + [CAP_SYS_CHROOT] = __stringify_1(CAP_SYS_CHROOT),
> + [CAP_SYS_PTRACE] = __stringify_1(CAP_SYS_PTRACE),
> + [CAP_SYS_PACCT] = __stringify_1(CAP_SYS_PACCT),
> + [CAP_SYS_ADMIN] = __stringify_1(CAP_SYS_ADMIN),
> + [CAP_SYS_BOOT] = __stringify_1(CAP_SYS_BOOT),
> + [CAP_SYS_NICE] = __stringify_1(CAP_SYS_NICE),
> + [CAP_SYS_RESOURCE] = __stringify_1(CAP_SYS_RESOURCE),
> + [CAP_SYS_TIME] = __stringify_1(CAP_SYS_TIME),
> + [CAP_SYS_TTY_CONFIG] = __stringify_1(CAP_SYS_TTY_CONFIG),
> + [CAP_MKNOD] = __stringify_1(CAP_MKNOD),
> + [CAP_LEASE] = __stringify_1(CAP_LEASE),
> + [CAP_AUDIT_WRITE] = __stringify_1(CAP_AUDIT_WRITE),
> + [CAP_AUDIT_CONTROL] = __stringify_1(CAP_AUDIT_CONTROL),
> + [CAP_SETFCAP] = __stringify_1(CAP_SETFCAP),
> + [CAP_MAC_OVERRIDE] = __stringify_1(CAP_MAC_OVERRIDE),
> + [CAP_MAC_ADMIN] = __stringify_1(CAP_MAC_ADMIN),
> + [CAP_SYSLOG] = __stringify_1(CAP_SYSLOG),
> + [CAP_WAKE_ALARM] = __stringify_1(CAP_WAKE_ALARM),
> + [CAP_BLOCK_SUSPEND] = __stringify_1(CAP_BLOCK_SUSPEND),
> + [CAP_AUDIT_READ] = __stringify_1(CAP_AUDIT_READ),
> + [CAP_PERFMON] = __stringify_1(CAP_PERFMON),
> + [CAP_BPF] = __stringify_1(CAP_BPF),
> + [CAP_CHECKPOINT_RESTORE] = __stringify_1(CAP_CHECKPOINT_RESTORE),
> +};
> +
> int file_caps_enabled = 1;
>
> static int __init file_caps_disable(char *str)
Hi.
Le lundi 27 d?cembre 2021, 23:26:29 CET Casey Schaufler a ?crit :
> On 12/27/2021 12:54 PM, Francis Laniel wrote:
> > This array contains the capability names for the given capabilitiy.
> > For example, index CAP_BPF contains "CAP_BPF".
> >
> > Signed-off-by: Francis Laniel <[email protected]>
> > ---
> >
> > include/uapi/linux/capability.h | 1 +
> > kernel/capability.c | 45 +++++++++++++++++++++++++++++++++
> > 2 files changed, 46 insertions(+)
> >
> > diff --git a/include/uapi/linux/capability.h
> > b/include/uapi/linux/capability.h index 463d1ba2232a..9646654d5111 100644
> > --- a/include/uapi/linux/capability.h
> > +++ b/include/uapi/linux/capability.h
> > @@ -428,5 +428,6 @@ struct vfs_ns_cap_data {
> >
> > #define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32
> > */
> > #define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed __u32
> > */
> >
> > +extern const char *cap_strings[];
> >
> > #endif /* _UAPI_LINUX_CAPABILITY_H */
> >
> > diff --git a/kernel/capability.c b/kernel/capability.c
> > index 46a361dde042..5a2e71dcd87b 100644
> > --- a/kernel/capability.c
> > +++ b/kernel/capability.c
> > @@ -15,6 +15,7 @@
> >
> > #include <linux/mm.h>
> > #include <linux/export.h>
> > #include <linux/security.h>
> >
> > +#include <linux/stringify.h>
> >
> > #include <linux/syscalls.h>
> > #include <linux/pid_namespace.h>
> > #include <linux/user_namespace.h>
> >
> > @@ -27,6 +28,50 @@
> >
> > const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET;
> > EXPORT_SYMBOL(__cap_empty_set);
> >
> > +const char *cap_strings[] = {
> > + [CAP_CHOWN] = __stringify_1(CAP_CHOWN),
>
> I may just be old and slow, but why is this better than
>
> [CAP_CHOWN] = "CAP_CHOWN",
Good catch, thank you for it, I just replaced the __stringify_1() by quotes.
I thought of using __stringify_() because at first I thought of adding a new
macro which would both define a new capability as well as adding to this array.
But I think it is better to with this simple way rather than doing complicated
stuff.
> > + [CAP_DAC_OVERRIDE] = __stringify_1(CAP_DAC_OVERRIDE),
> > + [CAP_DAC_READ_SEARCH] = __stringify_1(CAP_DAC_READ_SEARCH),
> > + [CAP_FOWNER] = __stringify_1(CAP_FOWNER),
> > + [CAP_FSETID] = __stringify_1(CAP_FSETID),
> > + [CAP_KILL] = __stringify_1(CAP_KILL),
> > + [CAP_SETGID] = __stringify_1(CAP_SETGID),
> > + [CAP_SETUID] = __stringify_1(CAP_SETUID),
> > + [CAP_SETPCAP] = __stringify_1(CAP_SETPCAP),
> > + [CAP_LINUX_IMMUTABLE] = __stringify_1(CAP_LINUX_IMMUTABLE),
> > + [CAP_NET_BIND_SERVICE] = __stringify_1(CAP_NET_BIND_SERVICE),
> > + [CAP_NET_BROADCAST] = __stringify_1(CAP_NET_BROADCAST),
> > + [CAP_NET_ADMIN] = __stringify_1(CAP_NET_ADMIN),
> > + [CAP_NET_RAW] = __stringify_1(CAP_NET_RAW),
> > + [CAP_IPC_LOCK] = __stringify_1(CAP_IPC_LOCK),
> > + [CAP_IPC_OWNER] = __stringify_1(CAP_IPC_OWNER),
> > + [CAP_SYS_MODULE] = __stringify_1(CAP_SYS_MODULE),
> > + [CAP_SYS_RAWIO] = __stringify_1(CAP_SYS_RAWIO),
> > + [CAP_SYS_CHROOT] = __stringify_1(CAP_SYS_CHROOT),
> > + [CAP_SYS_PTRACE] = __stringify_1(CAP_SYS_PTRACE),
> > + [CAP_SYS_PACCT] = __stringify_1(CAP_SYS_PACCT),
> > + [CAP_SYS_ADMIN] = __stringify_1(CAP_SYS_ADMIN),
> > + [CAP_SYS_BOOT] = __stringify_1(CAP_SYS_BOOT),
> > + [CAP_SYS_NICE] = __stringify_1(CAP_SYS_NICE),
> > + [CAP_SYS_RESOURCE] = __stringify_1(CAP_SYS_RESOURCE),
> > + [CAP_SYS_TIME] = __stringify_1(CAP_SYS_TIME),
> > + [CAP_SYS_TTY_CONFIG] = __stringify_1(CAP_SYS_TTY_CONFIG),
> > + [CAP_MKNOD] = __stringify_1(CAP_MKNOD),
> > + [CAP_LEASE] = __stringify_1(CAP_LEASE),
> > + [CAP_AUDIT_WRITE] = __stringify_1(CAP_AUDIT_WRITE),
> > + [CAP_AUDIT_CONTROL] = __stringify_1(CAP_AUDIT_CONTROL),
> > + [CAP_SETFCAP] = __stringify_1(CAP_SETFCAP),
> > + [CAP_MAC_OVERRIDE] = __stringify_1(CAP_MAC_OVERRIDE),
> > + [CAP_MAC_ADMIN] = __stringify_1(CAP_MAC_ADMIN),
> > + [CAP_SYSLOG] = __stringify_1(CAP_SYSLOG),
> > + [CAP_WAKE_ALARM] = __stringify_1(CAP_WAKE_ALARM),
> > + [CAP_BLOCK_SUSPEND] = __stringify_1(CAP_BLOCK_SUSPEND),
> > + [CAP_AUDIT_READ] = __stringify_1(CAP_AUDIT_READ),
> > + [CAP_PERFMON] = __stringify_1(CAP_PERFMON),
> > + [CAP_BPF] = __stringify_1(CAP_BPF),
> > + [CAP_CHECKPOINT_RESTORE] = __stringify_1(CAP_CHECKPOINT_RESTORE),
> > +};
> > +
> >
> > int file_caps_enabled = 1;
> >
> > static int __init file_caps_disable(char *str)
Hi.
Le lundi 27 d?cembre 2021, 23:22:41 CET Casey Schaufler a ?crit :
> On 12/27/2021 12:54 PM, Francis Laniel wrote:
> > Hi.
> >
> >
> > First, I hope you are fine and the same for your relatives.
> >
> > Capabilities are used to check if a thread has the right to perform a
> > given
> > action [1].
> > For example, a thread with CAP_BPF set can use the bpf() syscall.
> >
> > Capabilities are used in the container world.
> > In terms of code, several projects related to container maintain code
> > where the capabilities are written alike include/uapi/linux/capability.h
> > [2][3][4][5]. For these projects, their codebase should be updated when a
> > new capability is added to the kernel.
> > Some other projects rely on <sys/capability.h> [6].
> > In this case, this header file should reflect the capabilities offered by
> > the kernel.
> >
> > So, in this series, I added a new file to sysfs: /sys/kernel/capabilities.
>
> This should be /sys/kernel/security/capabilities.
I began to write code to move this under /sys/kernel/security/capabilities but
I realized this directory is linked to CONFIG_SECURITYFS.
This option is not required to be able to run container [1].
Also, kernel/capability.c is always compiled, so I think it is better if this
file (i.e. the one which prints capabilities to user) does not depend on any
CONFIG_.
What do you think of it? Does this sound acceptable for you?
> > The goal of this file is to be used by "container world" software to know
> > kernel capabilities at run time instead of compile time.
> >
> > The underlying kernel attribute is read-only and its content is the
> > capability number associated with the capability name:
> > root@vm-amd64:~# cat /sys/kernel/capabilities
> > 0 CAP_CHOWN
> > 1 CAP_DAC_OVERRIDE
> > ...
> > 39 CAP_BPF
> >
> > The kernel already exposes the last capability number under:
> > /proc/sys/kernel/cap_last_cap
> > So, I think there should not be any issue exposing all the capabilities it
> > offers.
> > If there is any, please share it as I do not want to introduce issue with
> > this series.
> >
> > Also, if you see any way to improve this series please share it as it
> > would
> > increase this contribution quality.
> >
> > Francis Laniel (2):
> > capability: Add cap_strings.
> > kernel/ksysfs.c: Add capabilities attribute.
> >
> > include/uapi/linux/capability.h | 1 +
> > kernel/capability.c | 45 +++++++++++++++++++++++++++++++++
> > kernel/ksysfs.c | 18 +++++++++++++
> > 3 files changed, 64 insertions(+)
> >
> > Best regards and thank you in advance for your reviews.
> > ---
> > [1] man capabilities
> > [2]
> > https://github.com/containerd/containerd/blob/1a078e6893d07fec10a4940a566
> > 4fab21d6f7d1e/pkg/cap/cap_linux.go#L135 [3]
> > https://github.com/moby/moby/commit/485cf38d48e7111b3d1f584d5e9eab46a902a
> > abc#diff-2e04625b209932e74c617de96682ed72fbd1bb0d0cb9fb7c709cf47a86b6f9c1
> > moby relies on containerd code.
> > [4]
> > https://github.com/syndtr/gocapability/blob/42c35b4376354fd554efc7ad35e0b
> > 7f94e3a0ffb/capability/enum.go#L47 [5]
> > https://github.com/opencontainers/runc/blob/00f56786bb220b55b41748231880b
> > a0e6380519a/libcontainer/capabilities/capabilities.go#L12 runc relies on
> > syndtr package.
> > [6]
> > https://github.com/containers/crun/blob/fafb556f09e6ffd4690c452ff51856b88
> > 0c089f1/src/libcrun/linux.c#L35
Best regards.
---
[1] https://github.com/moby/moby/blob/
10aecb0e652d346130a37e5b4383eca28f594c21/contrib/check-config.sh
On 12/28/2021 5:34 AM, Francis Laniel wrote:
> Hi.
>
> Le lundi 27 décembre 2021, 23:22:41 CET Casey Schaufler a écrit :
>> On 12/27/2021 12:54 PM, Francis Laniel wrote:
>>> Hi.
>>>
>>>
>>> First, I hope you are fine and the same for your relatives.
>>>
>>> Capabilities are used to check if a thread has the right to perform a
>>> given
>>> action [1].
>>> For example, a thread with CAP_BPF set can use the bpf() syscall.
>>>
>>> Capabilities are used in the container world.
>>> In terms of code, several projects related to container maintain code
>>> where the capabilities are written alike include/uapi/linux/capability.h
>>> [2][3][4][5]. For these projects, their codebase should be updated when a
>>> new capability is added to the kernel.
>>> Some other projects rely on <sys/capability.h> [6].
>>> In this case, this header file should reflect the capabilities offered by
>>> the kernel.
>>>
>>> So, in this series, I added a new file to sysfs: /sys/kernel/capabilities.
>> This should be /sys/kernel/security/capabilities.
> I began to write code to move this under /sys/kernel/security/capabilities but
> I realized this directory is linked to CONFIG_SECURITYFS.
> This option is not required to be able to run container [1].
You're going to need to handle the case where the file is missing
regardless. It is hard to design a kernel feature based on what a
container expects when there are so many definitions of a container.
> Also, kernel/capability.c is always compiled, so I think it is better if this
> file (i.e. the one which prints capabilities to user) does not depend on any
> CONFIG_.
CONFIG_MULTUSER is going to be an issue if you really care.
> What do you think of it? Does this sound acceptable for you?
Meh. I'm not going to get worked up over it, but your rationale
is a little weak.
>
>>> The goal of this file is to be used by "container world" software to know
>>> kernel capabilities at run time instead of compile time.
>>>
>>> The underlying kernel attribute is read-only and its content is the
>>> capability number associated with the capability name:
>>> root@vm-amd64:~# cat /sys/kernel/capabilities
>>> 0 CAP_CHOWN
>>> 1 CAP_DAC_OVERRIDE
>>> ...
>>> 39 CAP_BPF
>>>
>>> The kernel already exposes the last capability number under:
>>> /proc/sys/kernel/cap_last_cap
>>> So, I think there should not be any issue exposing all the capabilities it
>>> offers.
>>> If there is any, please share it as I do not want to introduce issue with
>>> this series.
>>>
>>> Also, if you see any way to improve this series please share it as it
>>> would
>>> increase this contribution quality.
>>>
>>> Francis Laniel (2):
>>> capability: Add cap_strings.
>>> kernel/ksysfs.c: Add capabilities attribute.
>>>
>>> include/uapi/linux/capability.h | 1 +
>>> kernel/capability.c | 45 +++++++++++++++++++++++++++++++++
>>> kernel/ksysfs.c | 18 +++++++++++++
>>> 3 files changed, 64 insertions(+)
>>>
>>> Best regards and thank you in advance for your reviews.
>>> ---
>>> [1] man capabilities
>>> [2]
>>> https://github.com/containerd/containerd/blob/1a078e6893d07fec10a4940a566
>>> 4fab21d6f7d1e/pkg/cap/cap_linux.go#L135 [3]
>>> https://github.com/moby/moby/commit/485cf38d48e7111b3d1f584d5e9eab46a902a
>>> abc#diff-2e04625b209932e74c617de96682ed72fbd1bb0d0cb9fb7c709cf47a86b6f9c1
>>> moby relies on containerd code.
>>> [4]
>>> https://github.com/syndtr/gocapability/blob/42c35b4376354fd554efc7ad35e0b
>>> 7f94e3a0ffb/capability/enum.go#L47 [5]
>>> https://github.com/opencontainers/runc/blob/00f56786bb220b55b41748231880b
>>> a0e6380519a/libcontainer/capabilities/capabilities.go#L12 runc relies on
>>> syndtr package.
>>> [6]
>>> https://github.com/containers/crun/blob/fafb556f09e6ffd4690c452ff51856b88
>>> 0c089f1/src/libcrun/linux.c#L35
>
> Best regards.
> ---
> [1] https://github.com/moby/moby/blob/
> 10aecb0e652d346130a37e5b4383eca28f594c21/contrib/check-config.sh
>
>
Le mercredi 29 d?cembre 2021, 02:26:20 CET Casey Schaufler a ?crit :
> On 12/28/2021 5:34 AM, Francis Laniel wrote:
> > Hi.
> >
> > Le lundi 27 d?cembre 2021, 23:22:41 CET Casey Schaufler a ?crit :
> >> On 12/27/2021 12:54 PM, Francis Laniel wrote:
> >>> Hi.
> >>>
> >>>
> >>> First, I hope you are fine and the same for your relatives.
> >>>
> >>> Capabilities are used to check if a thread has the right to perform a
> >>> given
> >>> action [1].
> >>> For example, a thread with CAP_BPF set can use the bpf() syscall.
> >>>
> >>> Capabilities are used in the container world.
> >>> In terms of code, several projects related to container maintain code
> >>> where the capabilities are written alike include/uapi/linux/capability.h
> >>> [2][3][4][5]. For these projects, their codebase should be updated when
> >>> a
> >>> new capability is added to the kernel.
> >>> Some other projects rely on <sys/capability.h> [6].
> >>> In this case, this header file should reflect the capabilities offered
> >>> by
> >>> the kernel.
> >>>
> >>> So, in this series, I added a new file to sysfs:
> >>> /sys/kernel/capabilities.
> >>
> >> This should be /sys/kernel/security/capabilities.
> >
> > I began to write code to move this under /sys/kernel/security/capabilities
> > but I realized this directory is linked to CONFIG_SECURITYFS.
> > This option is not required to be able to run container [1].
>
> You're going to need to handle the case where the file is missing
> regardless. It is hard to design a kernel feature based on what a
> container expects when there are so many definitions of a container.
The goal would be to always have this file, as if I need to handle the case
where it is missing, it surely means having hardcoded values for capabilities
like today situation.
I think it should be always here if its definition lies in a source file marked
as 'obj-y', right?
Nonetheless, I understand your point of having this "capabilities printing"
file under /sys/kernel/security.
But, this would lead to add CONFIG_SECURITYFS as a needed CONFIG_ to "run
container".
And, if "container stack" runs on a kernel which does not provide this option,
then "container software" would need to rely on hardcoded capabilities (like
today situation).
> > Also, kernel/capability.c is always compiled, so I think it is better if
> > this file (i.e. the one which prints capabilities to user) does not
> > depend on any CONFIG_.
>
> CONFIG_MULTUSER is going to be an issue if you really care.
I did not know about CONFIG_MULTIUSER and thinking a bit about at it, it
should be a needed CONFIG_ to run container.
Nonetheless, when CONFIG_MULTIUSER=n and if my understanding of 2813893f8b197
is correct, calling capset() leads to sys_ni_syscall() which returns -ENOSYS.
Thus, an user trying to "run container" with specific capabilities on a kernel
compiled with CONFIG_MULTIUSER=n will have trouble with all capabilities (and
will then have to first fix its CONFIG_ issue instead of knowing which
capabilities he/she can use).
> > What do you think of it? Does this sound acceptable for you?
>
> Meh. I'm not going to get worked up over it, but your rationale
> is a little weak.
I agree this contribution will not revolutionize how user interact with the
kernel.
But I see two advantages:
1. By removing hardcoded capabilities values from "container software", it
will ease these software maintainability.
Indeed, someone will not need to add new values to their code base when the
kernel get a new capability.
2. On the user side, without hardcoded capabilities values, you can use any
version of "container software" on a recent kernel to be able to use all the
capabilities the kernel offers.
For the anecdote, it was my case some time ago and I had to compile newer
version of "container software" to use underlying kernel capabilities [1].
This was not a big deal, but if this "container software" were capabilities
agnostic, it would have gain me a bit of time.
From this experience, I had the idea of this contribution.
> >>> The goal of this file is to be used by "container world" software to
> >>> know
> >>> kernel capabilities at run time instead of compile time.
> >>>
> >>> The underlying kernel attribute is read-only and its content is the
> >>> capability number associated with the capability name:
> >>> root@vm-amd64:~# cat /sys/kernel/capabilities
> >>> 0 CAP_CHOWN
> >>> 1 CAP_DAC_OVERRIDE
> >>> ...
> >>> 39 CAP_BPF
> >>>
> >>> The kernel already exposes the last capability number under:
> >>> /proc/sys/kernel/cap_last_cap
> >>> So, I think there should not be any issue exposing all the capabilities
> >>> it
> >>> offers.
> >>> If there is any, please share it as I do not want to introduce issue
> >>> with
> >>> this series.
> >>>
> >>> Also, if you see any way to improve this series please share it as it
> >>> would
> >>> increase this contribution quality.
> >>>
> >>> Francis Laniel (2):
> >>> capability: Add cap_strings.
> >>> kernel/ksysfs.c: Add capabilities attribute.
> >>>
> >>> include/uapi/linux/capability.h | 1 +
> >>> kernel/capability.c | 45
> >>> +++++++++++++++++++++++++++++++++
> >>> kernel/ksysfs.c | 18 +++++++++++++
> >>> 3 files changed, 64 insertions(+)
> >>>
> >>> Best regards and thank you in advance for your reviews.
> >>> ---
> >>> [1] man capabilities
> >>> [2]
> >>> https://github.com/containerd/containerd/blob/1a078e6893d07fec10a4940a56
> >>> 6
> >>> 4fab21d6f7d1e/pkg/cap/cap_linux.go#L135 [3]
> >>> https://github.com/moby/moby/commit/485cf38d48e7111b3d1f584d5e9eab46a902
> >>> a
> >>> abc#diff-2e04625b209932e74c617de96682ed72fbd1bb0d0cb9fb7c709cf47a86b6f9c
> >>> 1
> >>> moby relies on containerd code.
> >>> [4]
> >>> https://github.com/syndtr/gocapability/blob/42c35b4376354fd554efc7ad35e0
> >>> b
> >>> 7f94e3a0ffb/capability/enum.go#L47 [5]
> >>> https://github.com/opencontainers/runc/blob/00f56786bb220b55b41748231880
> >>> b
> >>> a0e6380519a/libcontainer/capabilities/capabilities.go#L12 runc relies on
> >>> syndtr package.
> >>> [6]
> >>> https://github.com/containers/crun/blob/fafb556f09e6ffd4690c452ff51856b8
> >>> 8
> >>> 0c089f1/src/libcrun/linux.c#L35
> >
> > Best regards.
> > ---
> > [1] https://github.com/moby/moby/blob/
> > 10aecb0e652d346130a37e5b4383eca28f594c21/contrib/check-config.sh
---
[1] https://github.com/kinvolk/minikube/commit/
51bf81c816c004ca0d0f3e3e368bc59f8a208387
On Tue, Dec 28, 2021 at 02:27:56PM +0100, Francis Laniel wrote:
> Hi.
>
>
> Le lundi 27 d?cembre 2021, 23:26:29 CET Casey Schaufler a ?crit :
> > On 12/27/2021 12:54 PM, Francis Laniel wrote:
> > > This array contains the capability names for the given capabilitiy.
> > > For example, index CAP_BPF contains "CAP_BPF".
> > >
> > > Signed-off-by: Francis Laniel <[email protected]>
> > > ---
> > >
> > > include/uapi/linux/capability.h | 1 +
> > > kernel/capability.c | 45 +++++++++++++++++++++++++++++++++
> > > 2 files changed, 46 insertions(+)
> > >
> > > diff --git a/include/uapi/linux/capability.h
> > > b/include/uapi/linux/capability.h index 463d1ba2232a..9646654d5111 100644
> > > --- a/include/uapi/linux/capability.h
> > > +++ b/include/uapi/linux/capability.h
> > > @@ -428,5 +428,6 @@ struct vfs_ns_cap_data {
> > >
> > > #define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32
> > > */
> > > #define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed __u32
> > > */
> > >
> > > +extern const char *cap_strings[];
> > >
> > > #endif /* _UAPI_LINUX_CAPABILITY_H */
> > >
> > > diff --git a/kernel/capability.c b/kernel/capability.c
> > > index 46a361dde042..5a2e71dcd87b 100644
> > > --- a/kernel/capability.c
> > > +++ b/kernel/capability.c
> > > @@ -15,6 +15,7 @@
> > >
> > > #include <linux/mm.h>
> > > #include <linux/export.h>
> > > #include <linux/security.h>
> > >
> > > +#include <linux/stringify.h>
> > >
> > > #include <linux/syscalls.h>
> > > #include <linux/pid_namespace.h>
> > > #include <linux/user_namespace.h>
> > >
> > > @@ -27,6 +28,50 @@
> > >
> > > const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET;
> > > EXPORT_SYMBOL(__cap_empty_set);
> > >
> > > +const char *cap_strings[] = {
> > > + [CAP_CHOWN] = __stringify_1(CAP_CHOWN),
> >
> > I may just be old and slow, but why is this better than
> >
> > [CAP_CHOWN] = "CAP_CHOWN",
>
> Good catch, thank you for it, I just replaced the __stringify_1() by quotes.
> I thought of using __stringify_() because at first I thought of adding a new
> macro which would both define a new capability as well as adding to this array.
I think you are saying you have a new version of the patch where you do
what Casey suggests, but I don't see it. Have you sent an updated patch,
or am I misunderstanding?
> But I think it is better to with this simple way rather than doing complicated
> stuff.
>
> > > + [CAP_DAC_OVERRIDE] = __stringify_1(CAP_DAC_OVERRIDE),
> > > + [CAP_DAC_READ_SEARCH] = __stringify_1(CAP_DAC_READ_SEARCH),
> > > + [CAP_FOWNER] = __stringify_1(CAP_FOWNER),
> > > + [CAP_FSETID] = __stringify_1(CAP_FSETID),
> > > + [CAP_KILL] = __stringify_1(CAP_KILL),
> > > + [CAP_SETGID] = __stringify_1(CAP_SETGID),
> > > + [CAP_SETUID] = __stringify_1(CAP_SETUID),
> > > + [CAP_SETPCAP] = __stringify_1(CAP_SETPCAP),
> > > + [CAP_LINUX_IMMUTABLE] = __stringify_1(CAP_LINUX_IMMUTABLE),
> > > + [CAP_NET_BIND_SERVICE] = __stringify_1(CAP_NET_BIND_SERVICE),
> > > + [CAP_NET_BROADCAST] = __stringify_1(CAP_NET_BROADCAST),
> > > + [CAP_NET_ADMIN] = __stringify_1(CAP_NET_ADMIN),
> > > + [CAP_NET_RAW] = __stringify_1(CAP_NET_RAW),
> > > + [CAP_IPC_LOCK] = __stringify_1(CAP_IPC_LOCK),
> > > + [CAP_IPC_OWNER] = __stringify_1(CAP_IPC_OWNER),
> > > + [CAP_SYS_MODULE] = __stringify_1(CAP_SYS_MODULE),
> > > + [CAP_SYS_RAWIO] = __stringify_1(CAP_SYS_RAWIO),
> > > + [CAP_SYS_CHROOT] = __stringify_1(CAP_SYS_CHROOT),
> > > + [CAP_SYS_PTRACE] = __stringify_1(CAP_SYS_PTRACE),
> > > + [CAP_SYS_PACCT] = __stringify_1(CAP_SYS_PACCT),
> > > + [CAP_SYS_ADMIN] = __stringify_1(CAP_SYS_ADMIN),
> > > + [CAP_SYS_BOOT] = __stringify_1(CAP_SYS_BOOT),
> > > + [CAP_SYS_NICE] = __stringify_1(CAP_SYS_NICE),
> > > + [CAP_SYS_RESOURCE] = __stringify_1(CAP_SYS_RESOURCE),
> > > + [CAP_SYS_TIME] = __stringify_1(CAP_SYS_TIME),
> > > + [CAP_SYS_TTY_CONFIG] = __stringify_1(CAP_SYS_TTY_CONFIG),
> > > + [CAP_MKNOD] = __stringify_1(CAP_MKNOD),
> > > + [CAP_LEASE] = __stringify_1(CAP_LEASE),
> > > + [CAP_AUDIT_WRITE] = __stringify_1(CAP_AUDIT_WRITE),
> > > + [CAP_AUDIT_CONTROL] = __stringify_1(CAP_AUDIT_CONTROL),
> > > + [CAP_SETFCAP] = __stringify_1(CAP_SETFCAP),
> > > + [CAP_MAC_OVERRIDE] = __stringify_1(CAP_MAC_OVERRIDE),
> > > + [CAP_MAC_ADMIN] = __stringify_1(CAP_MAC_ADMIN),
> > > + [CAP_SYSLOG] = __stringify_1(CAP_SYSLOG),
> > > + [CAP_WAKE_ALARM] = __stringify_1(CAP_WAKE_ALARM),
> > > + [CAP_BLOCK_SUSPEND] = __stringify_1(CAP_BLOCK_SUSPEND),
> > > + [CAP_AUDIT_READ] = __stringify_1(CAP_AUDIT_READ),
> > > + [CAP_PERFMON] = __stringify_1(CAP_PERFMON),
> > > + [CAP_BPF] = __stringify_1(CAP_BPF),
> > > + [CAP_CHECKPOINT_RESTORE] = __stringify_1(CAP_CHECKPOINT_RESTORE),
> > > +};
> > > +
> > >
> > > int file_caps_enabled = 1;
> > >
> > > static int __init file_caps_disable(char *str)
>
>
>
Hi.
Le vendredi 14 janvier 2022, 01:39:10 CET Serge E. Hallyn a ?crit :
> On Tue, Dec 28, 2021 at 02:27:56PM +0100, Francis Laniel wrote:
> > Hi.
> >
> > Le lundi 27 d?cembre 2021, 23:26:29 CET Casey Schaufler a ?crit :
> > > On 12/27/2021 12:54 PM, Francis Laniel wrote:
> > > > This array contains the capability names for the given capabilitiy.
> > > > For example, index CAP_BPF contains "CAP_BPF".
> > > >
> > > > Signed-off-by: Francis Laniel <[email protected]>
> > > > ---
> > > >
> > > > include/uapi/linux/capability.h | 1 +
> > > > kernel/capability.c | 45
> > > > +++++++++++++++++++++++++++++++++
> > > > 2 files changed, 46 insertions(+)
> > > >
> > > > diff --git a/include/uapi/linux/capability.h
> > > > b/include/uapi/linux/capability.h index 463d1ba2232a..9646654d5111
> > > > 100644
> > > > --- a/include/uapi/linux/capability.h
> > > > +++ b/include/uapi/linux/capability.h
> > > > @@ -428,5 +428,6 @@ struct vfs_ns_cap_data {
> > > >
> > > > #define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in
> > > > __u32
> > > > */
> > > > #define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed
> > > > __u32
> > > > */
> > > >
> > > > +extern const char *cap_strings[];
> > > >
> > > > #endif /* _UAPI_LINUX_CAPABILITY_H */
> > > >
> > > > diff --git a/kernel/capability.c b/kernel/capability.c
> > > > index 46a361dde042..5a2e71dcd87b 100644
> > > > --- a/kernel/capability.c
> > > > +++ b/kernel/capability.c
> > > > @@ -15,6 +15,7 @@
> > > >
> > > > #include <linux/mm.h>
> > > > #include <linux/export.h>
> > > > #include <linux/security.h>
> > > >
> > > > +#include <linux/stringify.h>
> > > >
> > > > #include <linux/syscalls.h>
> > > > #include <linux/pid_namespace.h>
> > > > #include <linux/user_namespace.h>
> > > >
> > > > @@ -27,6 +28,50 @@
> > > >
> > > > const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET;
> > > > EXPORT_SYMBOL(__cap_empty_set);
> > > >
> > > > +const char *cap_strings[] = {
> > > > + [CAP_CHOWN] = __stringify_1(CAP_CHOWN),
> > >
> > > I may just be old and slow, but why is this better than
> > >
> > > [CAP_CHOWN] = "CAP_CHOWN",
> >
> > Good catch, thank you for it, I just replaced the __stringify_1() by
> > quotes. I thought of using __stringify_() because at first I thought of
> > adding a new macro which would both define a new capability as well as
> > adding to this array.
> I think you are saying you have a new version of the patch where you do
> what Casey suggests, but I don't see it. Have you sent an updated patch,
> or am I misunderstanding?
Sorry, I forgot to send it as we were thinking on the right place to put the
sysfs with Casey.
I normally have send it two minutes ago.
> > But I think it is better to with this simple way rather than doing
> > complicated stuff.
> >
> > > > + [CAP_DAC_OVERRIDE] = __stringify_1(CAP_DAC_OVERRIDE),
> > > > + [CAP_DAC_READ_SEARCH] = __stringify_1(CAP_DAC_READ_SEARCH),
> > > > + [CAP_FOWNER] = __stringify_1(CAP_FOWNER),
> > > > + [CAP_FSETID] = __stringify_1(CAP_FSETID),
> > > > + [CAP_KILL] = __stringify_1(CAP_KILL),
> > > > + [CAP_SETGID] = __stringify_1(CAP_SETGID),
> > > > + [CAP_SETUID] = __stringify_1(CAP_SETUID),
> > > > + [CAP_SETPCAP] = __stringify_1(CAP_SETPCAP),
> > > > + [CAP_LINUX_IMMUTABLE] = __stringify_1(CAP_LINUX_IMMUTABLE),
> > > > + [CAP_NET_BIND_SERVICE] = __stringify_1(CAP_NET_BIND_SERVICE),
> > > > + [CAP_NET_BROADCAST] = __stringify_1(CAP_NET_BROADCAST),
> > > > + [CAP_NET_ADMIN] = __stringify_1(CAP_NET_ADMIN),
> > > > + [CAP_NET_RAW] = __stringify_1(CAP_NET_RAW),
> > > > + [CAP_IPC_LOCK] = __stringify_1(CAP_IPC_LOCK),
> > > > + [CAP_IPC_OWNER] = __stringify_1(CAP_IPC_OWNER),
> > > > + [CAP_SYS_MODULE] = __stringify_1(CAP_SYS_MODULE),
> > > > + [CAP_SYS_RAWIO] = __stringify_1(CAP_SYS_RAWIO),
> > > > + [CAP_SYS_CHROOT] = __stringify_1(CAP_SYS_CHROOT),
> > > > + [CAP_SYS_PTRACE] = __stringify_1(CAP_SYS_PTRACE),
> > > > + [CAP_SYS_PACCT] = __stringify_1(CAP_SYS_PACCT),
> > > > + [CAP_SYS_ADMIN] = __stringify_1(CAP_SYS_ADMIN),
> > > > + [CAP_SYS_BOOT] = __stringify_1(CAP_SYS_BOOT),
> > > > + [CAP_SYS_NICE] = __stringify_1(CAP_SYS_NICE),
> > > > + [CAP_SYS_RESOURCE] = __stringify_1(CAP_SYS_RESOURCE),
> > > > + [CAP_SYS_TIME] = __stringify_1(CAP_SYS_TIME),
> > > > + [CAP_SYS_TTY_CONFIG] = __stringify_1(CAP_SYS_TTY_CONFIG),
> > > > + [CAP_MKNOD] = __stringify_1(CAP_MKNOD),
> > > > + [CAP_LEASE] = __stringify_1(CAP_LEASE),
> > > > + [CAP_AUDIT_WRITE] = __stringify_1(CAP_AUDIT_WRITE),
> > > > + [CAP_AUDIT_CONTROL] = __stringify_1(CAP_AUDIT_CONTROL),
> > > > + [CAP_SETFCAP] = __stringify_1(CAP_SETFCAP),
> > > > + [CAP_MAC_OVERRIDE] = __stringify_1(CAP_MAC_OVERRIDE),
> > > > + [CAP_MAC_ADMIN] = __stringify_1(CAP_MAC_ADMIN),
> > > > + [CAP_SYSLOG] = __stringify_1(CAP_SYSLOG),
> > > > + [CAP_WAKE_ALARM] = __stringify_1(CAP_WAKE_ALARM),
> > > > + [CAP_BLOCK_SUSPEND] = __stringify_1(CAP_BLOCK_SUSPEND),
> > > > + [CAP_AUDIT_READ] = __stringify_1(CAP_AUDIT_READ),
> > > > + [CAP_PERFMON] = __stringify_1(CAP_PERFMON),
> > > > + [CAP_BPF] = __stringify_1(CAP_BPF),
> > > > + [CAP_CHECKPOINT_RESTORE] =
__stringify_1(CAP_CHECKPOINT_RESTORE),
> > > > +};
> > > > +
> > > >
> > > > int file_caps_enabled = 1;
> > > >
> > > > static int __init file_caps_disable(char *str)