>> All that being said, the friendliness factor of this is somewhat >> undeniable, and so I can see why folk might want it in the kernel >> anyway. If so, would it possible to move this code into >> security/capability.c and not in the main kernel per-se - protected with >> a configuration option? If it does appear in the kernel, we'll obviously >> add your libcap changes too. If it doesn't, then perhaps we can meet >> your needs with a slight modification to your libcap patch to read the >> capabilities from an optional /etc/XXX file - and make text visibility >> of 'late breaking' capabilities something that the admin can tweak as >> needed? > > I think optional configuration file is not a good idea. > It can make unneeded confusion. > > If necessary, I'll move this features into security/capability.c and > add a Kconfig option to select it.
The following patch enables to export the list of capabilities supported on the running kernel, under /sys/kernel/capability . Changelog from the previous version: - Implementation is moved into security/capability.c from kernel/capability.c - A Kconfig option SECURITY_CAPABILITIES_EXPORT is added to tuen on/off this feature. [EMAIL PROTECTED] ~]$ for x in /sys/kernel/capability/* > do > echo "$x --> `cat $x`" > done /sys/kernel/capability/cap_audit_control --> 30 /sys/kernel/capability/cap_audit_write --> 29 - snip - /sys/kernel/capability/cap_sys_time --> 25 /sys/kernel/capability/cap_sys_tty_config --> 26 /sys/kernel/capability/index --> 31 /sys/kernel/capability/version --> 0x19980330 [EMAIL PROTECTED] ~]$ Thanks, Signed-off-by: KaiGai Kohei <[EMAIL PROTECTED]> ---- scripts/mkcapnames.sh | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ security/Kconfig | 9 ++++++++ security/Makefile | 11 ++++++++++ security/capability.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 0 deletions(-) diff --git a/scripts/mkcapnames.sh b/scripts/mkcapnames.sh index e69de29..262478e 100644 --- a/scripts/mkcapnames.sh +++ b/scripts/mkcapnames.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +# +# generate a cap_names.h file from include/linux/capability.h +# + +BASEDIR=`dirname $0` + +echo '#ifndef CAP_NAMES_H' +echo '#define CAP_NAMES_H' +echo +echo '/*' +echo ' * Do NOT edit this file directly.' +echo ' * This file is generated from include/linux/capability.h automatically' +echo ' */' +echo +echo '#ifndef SYSFS_CAPABILITY_ENTRY' +echo '#error cap_names.h should be included from kernel/capability.c' +echo '#else' + +echo 'SYSFS_CAPABILITY_ENTRY(version, "0x%08x\n", _LINUX_CAPABILITY_VERSION);' + +cat ${BASEDIR}/../include/linux/capability.h \ + | egrep '^#define CAP_[A-Z_]+[ ]+[0-9]+$' \ + | awk 'BEGIN { + max_code = -1; + } + { + if ($3 > max_code) + max_code = $3; + printf("SYSFS_CAPABILITY_ENTRY(%s, \"%%u\\n\", %s);\n", tolower($2), $2); + } + END { + printf("SYSFS_CAPABILITY_ENTRY(index, \"%%u\\n\", %u);\n", max_code); + }' + +echo +echo 'static struct attribute *capability_attrs[] = {' +echo ' &version_attr.attr,' +echo ' &index_attr.attr,' + +cat ${BASEDIR}/../include/linux/capability.h \ + | egrep '^#define CAP_[A-Z_]+[ ]+[0-9]+$' \ + | awk '{ printf (" &%s_attr.attr,\n", tolower($2)); }' + +echo ' NULL,' +echo '};' + +echo '#endif /* SYSFS_CAPABILITY_ENTRY */' +echo '#endif /* CAP_NAMES_H */' diff --git a/security/Kconfig b/security/Kconfig index 8086e61..e4d330c 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -90,6 +90,15 @@ config SECURITY_FILE_CAPABILITIES If in doubt, answer N. +config SECURITY_CAPABILITIES_EXPORT + bool "Exporting capabilities kernel supported" + depends on SECURITY_CAPABILITIES && SYSFS + help + This enables to export any capabilities which are supported + in the running kernel. + + If you are unsure how to answer this question, answer Y. + config SECURITY_ROOTPLUG bool "Root Plug Support" depends on USB=y && SECURITY diff --git a/security/Makefile b/security/Makefile index ef87df2..90a856d 100644 --- a/security/Makefile +++ b/security/Makefile @@ -16,3 +16,14 @@ obj-$(CONFIG_SECURITY) += security.o dummy.o inode.o obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o + +ifeq ($(CONFIG_SECURITY_CAPABILITIES_EXPORT),y) +# cap_names.h contains the code/name pair of capabilities. +# It is generated using include/linux/capability.h automatically. +$(obj)/capability.o: $(obj)/cap_names.h +quiet_cmd_cap_names = CAPS $@ + cmd_cap_names = /bin/sh $(src)/../scripts/mkcapnames.sh > $@ +targets += cap_names.h +$(obj)/cap_names.h: $(src)/../scripts/mkcapnames.sh $(src)/../include/linux/capability.h FORCE + $(call if_changed,cap_names) +endif diff --git a/security/capability.c b/security/capability.c index 9e99f36..06e0f0a 100644 --- a/security/capability.c +++ b/security/capability.c @@ -20,6 +20,8 @@ #include <linux/netlink.h> #include <linux/ptrace.h> #include <linux/moduleparam.h> +#include <linux/kobject.h> +#include <linux/sysfs.h> static struct security_operations capability_ops = { .ptrace = cap_ptrace, @@ -58,6 +60,53 @@ static int secondary; static int capability_disable; module_param_named(disable, capability_disable, int, 0); +#ifdef CONFIG_SECURITY_CAPABILITIES_EXPORT +/* + * Export the list of capabilities on /sys/kernel/capability + */ +struct capability_attribute { + struct attribute attr; + ssize_t (*show)(struct kobject *kobj, + struct capability_attribute *attr, + char *buffer); + ssize_t (*store)(struct kobject *kobj, + struct capability_attribute *attr, + const char *buffer, size_t count); +}; + +#define SYSFS_CAPABILITY_ENTRY(_name, _fmt, ...) \ + static ssize_t _name##_show(struct kobject *kobj, \ + struct capability_attribute *attr, \ + char *buffer) \ + { \ + return scnprintf(buffer, PAGE_SIZE, _fmt, __VA_ARGS__); \ + } \ + static struct capability_attribute _name##_attr = __ATTR_RO(_name) +/* + * capability_attrs[] is generated automatically by scripts/mkcapnames.sh + * This script parses include/linux/capability.h + */ +#include "cap_names.h" + +static struct attribute_group capability_attr_group = { + .name = "capability", + .attrs = capability_attrs, +}; + +static int __init capability_export_names(void) +{ + int rc; + + rc = sysfs_create_group(kernel_kobj, &capability_attr_group); + if (rc) { + printk(KERN_ERR "Unable to export capabilities\n"); + return rc; + } + return 0; +} +__initcall(capability_export_names); +#endif + static int __init capability_init (void) { if (capability_disable) { -- OSS Platform Development Division, NEC KaiGai Kohei <[EMAIL PROTECTED]> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/