Exporting capability code/name pairs
Subsystems (2)
PATCH 1/1 Exporting capability code/name pairs
This patch enables to export the code/name pairs of capabilities under /capability of securityfs.
In the current libcap, it obtains the list of capabilities from header file on the build environment statically. However, it is not enough portable between different versions of kernels, because an already built libcap cannot have knowledge about new added capabilities.
Dynamic collection of code/name pairs of capabilities will resolve this matter.
But it is not perfect one. I have a bit concern about this patch now.
1. I want to generate cap_entries array from linux/capability.h automatically. Is there any good idea?
2. We have to mount securityfs explicitly, or using /etc/fstab. It can make a matter when we want to use this features in very early boot sequence.
Any comment please.
usage:
-----------------------------------------------
# mount -t securityfs none /sys/kernel/security # cd /sys/kernel/security/capability # ls cap_audit_control cap_kill cap_setpcap cap_sys_rawio cap_audit_write cap_lease cap_setuid cap_sys_resource cap_chown cap_linux_immutable cap_sys_admin cap_sys_time cap_dac_override cap_mknod cap_sys_boot cap_sys_tty_config cap_dac_read_search cap_net_admin cap_sys_chroot index cap_fowner cap_net_bind_service cap_sys_module version cap_fsetid cap_net_broadcast cap_sys_nice cap_ipc_lock cap_setfcap cap_sys_pacct cap_ipc_owner cap_setgid cap_sys_ptrace # cat cap_audit_write ; echo 29 # cat cap_sys_chroot ; echo 18 # cat version ; echo 0x19980330 # cat index; echo 31 #
Signature · 7 lines
OSS Platform Development Division, NEC KaiGai Kohei <[email protected]> Signed-off-by: KaiGai Kohei <[email protected]> --- capability.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+)
kernel/capability.c +127 -0
@@ -245,3 +245,131 @@ int capable(int cap)return __capable (current, cap); }EXPORT_SYMBOL (capable); + +/* +* Capability code/name pair exporting +*/ + +/* +* capability code/name pairs are exported under /sys/security/capability/ +*/ +struct cap_entry_data { +unsigned int code; +const char *name; +}; + +static struct cap_entry_data cap_entries[] = { +/* max number of supported format */ + { _LINUX_CAPABILITY_VERSION,"version" }, +/* max number of capability */ + {CAP_LAST_CAP ,"index" }, +/* list of capabilities */ + {CAP_CHOWN ,"cap_chown" }, + {CAP_DAC_OVERRIDE ,"cap_dac_override" }, + {CAP_DAC_READ_SEARCH ,"cap_dac_read_search" }, + {CAP_FOWNER ,"cap_fowner" }, + {CAP_FSETID ,"cap_fsetid" }, + {CAP_KILL ,"cap_kill" }, + {CAP_SETGID ,"cap_setgid" }, + {CAP_SETUID ,"cap_setuid" }, + {CAP_SETPCAP ,"cap_setpcap" }, + {CAP_LINUX_IMMUTABLE ,"cap_linux_immutable" }, + {CAP_NET_BIND_SERVICE ,"cap_net_bind_service" }, + {CAP_NET_BROADCAST ,"cap_net_broadcast" }, + {CAP_NET_ADMIN ,"cap_net_admin" }, + {CAP_NET_RAW ,"cap_net_admin" }, + {CAP_IPC_LOCK ,"cap_ipc_lock" }, + {CAP_IPC_OWNER ,"cap_ipc_owner" }, + {CAP_SYS_MODULE ,"cap_sys_module" }, + {CAP_SYS_RAWIO ,"cap_sys_rawio" }, + {CAP_SYS_CHROOT ,"cap_sys_chroot" }, + {CAP_SYS_PTRACE ,"cap_sys_ptrace" }, + {CAP_SYS_PACCT ,"cap_sys_pacct" }, + {CAP_SYS_ADMIN ,"cap_sys_admin" }, + {CAP_SYS_BOOT ,"cap_sys_boot" }, + {CAP_SYS_NICE ,"cap_sys_nice" }, + {CAP_SYS_RESOURCE ,"cap_sys_resource" }, + {CAP_SYS_TIME ,"cap_sys_time" }, + {CAP_SYS_TTY_CONFIG ,"cap_sys_tty_config" }, + {CAP_MKNOD ,"cap_mknod" }, + {CAP_LEASE ,"cap_lease" }, + {CAP_AUDIT_WRITE ,"cap_audit_write" }, + {CAP_AUDIT_CONTROL ,"cap_audit_control" }, + {CAP_SETFCAP ,"cap_setfcap" }, + {CAP_MAC_OVERRIDE ,"cap_mac_override" }, + {CAP_MAC_ADMIN ,"cap_mac_admin" }, + {-1 ,NULL }, +}; + +static ssize_t cap_entry_read (struct file *file,char __user *buffer, +size_t count,loff_t *ppos) +{ +struct cap_entry_data *cap_entry; +size_t len, ofs = *ppos; +char tmp[32 ]; +int rc; + + cap_entry = file->f_dentry->d_inode->i_private; +if (!cap_entry) +return -EINVAL ; + +if (cap_entry == &cap_entries[0 ]) { +/* 'version' entry*/ +snprintf (tmp,sizeof (tmp),"0x%08x" , cap_entry->code); + }else { +snprintf (tmp,sizeof (tmp),"%u" , cap_entry->code); + } + len =strlen (tmp); + +if (ofs >= len) +return 0 ; + +if (len - ofs < count) + count = len - ofs; + + rc =copy_to_user (buffer, tmp + ofs, count); +if (rc) +return rc; + + *ppos += count; +return count; +} + +const struct file_operations cap_entry_fops = { + .read = cap_entry_read, +}; + +int __init cap_names_export (void ) +{ +struct dentry *d_caps, *f_caps[ARRAY_SIZE (cap_entries)]; +int i; + + d_caps =securityfs_create_dir ("capability" ,NULL ); +if (!d_caps) + goto error0; + +memset (f_caps,0 ,sizeof (f_caps)); +for (i =0 ; cap_entries[i].name; i++) { + f_caps[i] =securityfs_create_file (cap_entries[i].name,0444 , + d_caps, &cap_entries[i], + &cap_entry_fops); +if (!f_caps[i]) + goto error1; + } +printk (KERN_NOTICE "capability code/name pairs are exported\n" ); +return 0 ; + +error1: +while (i >0 ) { + i--; +securityfs_remove (f_caps[i]); + } +securityfs_remove (d_caps); +error0: +printk (KERN_ERR "Unable to export capability code/name pairs\n" ); + +return 0 ; +} + +__initcall (cap_names_export);
On Thu, 27 Dec 2007, KaiGai Kohei wrote:
(Please put the patch above the .sig separator).
+ len = strlen(tmp);
+
+ if (ofs >= len)
+ return 0;
+
+ if (len - ofs < count)
+ count = len - ofs;
+
+ rc = copy_to_user(buffer, tmp + ofs, count);
+ if (rc)
+ return rc;
+
+ *ppos += count;
Use simple_read_from_buffer().
- James
Signature · 2 lines
James Morris <[email protected]>
Quoted 13 lines · KaiGai Kohei
This patch enables to export the code/name pairs of capabilities under /capability of securityfs.
In the current libcap, it obtains the list of capabilities from header file on the build environment statically. However, it is not enough portable between different versions of kernels, because an already built libcap cannot have knowledge about new added capabilities.
Dynamic collection of code/name pairs of capabilities will resolve this matter.
But it is not perfect one. I have a bit concern about this patch now.
Quoted 7 lines
1. I want to generate
cap_entriesarray fromlinux/capability.hautomatically. Is there any good idea?
2. We have to mount securityfs explicitly, or using/etc/fstab. It can make a matter when we want to use this features in very early boot sequence.Any comment please.
I like the idea, but
Quoted 86 lines
usage:
-----------------------------------------------# mount -t securityfs none /sys/kernel/security # cd /sys/kernel/security/capability # ls cap_audit_control cap_kill cap_setpcap cap_sys_rawio cap_audit_write cap_lease cap_setuid cap_sys_resource cap_chown cap_linux_immutable cap_sys_admin cap_sys_time cap_dac_override cap_mknod cap_sys_boot cap_sys_tty_config cap_dac_read_search cap_net_admin cap_sys_chroot index cap_fowner cap_net_bind_service cap_sys_module version cap_fsetid cap_net_broadcast cap_sys_nice cap_ipc_lock cap_setfcap cap_sys_pacct cap_ipc_owner cap_setgid cap_sys_ptrace # cat cap_audit_write ; echo 29 # cat cap_sys_chroot ; echo 18 # cat version ; echo 0x19980330 # cat index; echo 31 #Signature · 7 lines
OSS Platform Development Division, NEC KaiGai Kohei <[email protected]> Signed-off-by: KaiGai Kohei <[email protected]> --- capability.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+)kernel/capability.c +45
-0@@ -245,3 +245,131 @@ int capable(int cap)return __capable (current, cap); }EXPORT_SYMBOL (capable); + +/* +* Capability code/name pair exporting +*/ + +/* +* capability code/name pairs are exported under /sys/security/capability/ +*/ +struct cap_entry_data { +unsigned int code; +const char *name; +}; + +static struct cap_entry_data cap_entries[] = { +/* max number of supported format */ + { _LINUX_CAPABILITY_VERSION,"version" }, +/* max number of capability */ + {CAP_LAST_CAP ,"index" }, +/* list of capabilities */ + {CAP_CHOWN ,"cap_chown" }, + {CAP_DAC_OVERRIDE ,"cap_dac_override" }, + {CAP_DAC_READ_SEARCH ,"cap_dac_read_search" }, + {CAP_FOWNER ,"cap_fowner" }, + {CAP_FSETID ,"cap_fsetid" }, + {CAP_KILL ,"cap_kill" }, + {CAP_SETGID ,"cap_setgid" }, + {CAP_SETUID ,"cap_setuid" }, + {CAP_SETPCAP ,"cap_setpcap" }, + {CAP_LINUX_IMMUTABLE ,"cap_linux_immutable" }, + {CAP_NET_BIND_SERVICE ,"cap_net_bind_service" }, + {CAP_NET_BROADCAST ,"cap_net_broadcast" }, + {CAP_NET_ADMIN ,"cap_net_admin" }, + {CAP_NET_RAW ,"cap_net_admin" }, + {CAP_IPC_LOCK ,"cap_ipc_lock" }, + {CAP_IPC_OWNER ,"cap_ipc_owner" }, + {CAP_SYS_MODULE ,"cap_sys_module" }, + {CAP_SYS_RAWIO ,"cap_sys_rawio" }, + {CAP_SYS_CHROOT ,"cap_sys_chroot" }, + {CAP_SYS_PTRACE ,"cap_sys_ptrace" }, + {CAP_SYS_PACCT ,"cap_sys_pacct" }, + {CAP_SYS_ADMIN ,"cap_sys_admin" }, + {CAP_SYS_BOOT ,"cap_sys_boot" }, + {CAP_SYS_NICE ,"cap_sys_nice" }, + {CAP_SYS_RESOURCE ,"cap_sys_resource" }, + {CAP_SYS_TIME ,"cap_sys_time" },
kernel/capability.c int capable(int cap) · line 302
Quoted 10 lines
kernel/capability.c +10
-0+ { CAP_SYS_TTY_CONFIG, "cap_sys_tty_config" }, + { CAP_MKNOD, "cap_mknod" }, + { CAP_LEASE, "cap_lease" }, + { CAP_AUDIT_WRITE, "cap_audit_write" }, + { CAP_AUDIT_CONTROL, "cap_audit_control" }, + { CAP_SETFCAP, "cap_setfcap" }, + { CAP_MAC_OVERRIDE, "cap_mac_override" }, + { CAP_MAC_ADMIN, "cap_mac_admin" }, + { -1, NULL}, +};
I don't like this duplication with the list in include/linux/capability.h. Now when a new cap is added, it needs to be
1. added to capability.h
2. swapped as the new CAP_LAST_CAP in capability.h
3. added to this list...
Could you integrate the two lists (not sure how offhand), or at least put them in the same place?
Quoted 71 lines
kernel/capability.c +71
-0+static ssize_t cap_entry_read (struct file *file,char __user *buffer, +size_t count,loff_t *ppos) +{ +struct cap_entry_data *cap_entry; +size_t len, ofs = *ppos; +char tmp[32 ]; +int rc; + + cap_entry = file->f_dentry->d_inode->i_private; +if (!cap_entry) +return -EINVAL ; + +if (cap_entry == &cap_entries[0 ]) { +/* 'version' entry*/ +snprintf (tmp,sizeof (tmp),"0x%08x" , cap_entry->code); + }else { +snprintf (tmp,sizeof (tmp),"%u" , cap_entry->code); + } + len =strlen (tmp); + +if (ofs >= len) +return 0 ; + +if (len - ofs < count) + count = len - ofs; + + rc =copy_to_user (buffer, tmp + ofs, count); +if (rc) +return rc; + + *ppos += count; +return count; +} + +const struct file_operations cap_entry_fops = { + .read = cap_entry_read, +}; + +int __init cap_names_export (void ) +{ +struct dentry *d_caps, *f_caps[ARRAY_SIZE (cap_entries)]; +int i; + + d_caps =securityfs_create_dir ("capability" ,NULL ); +if (!d_caps) + goto error0; + +memset (f_caps,0 ,sizeof (f_caps)); +for (i =0 ; cap_entries[i].name; i++) { + f_caps[i] =securityfs_create_file (cap_entries[i].name,0444 , + d_caps, &cap_entries[i], + &cap_entry_fops); +if (!f_caps[i]) + goto error1; + } +printk (KERN_NOTICE "capability code/name pairs are exported\n" ); +return 0 ; + +error1: +while (i >0 ) { + i--; +securityfs_remove (f_caps[i]); + } +securityfs_remove (d_caps); +error0: +printk (KERN_ERR "Unable to export capability code/name pairs\n" ); + +return 0 ; +} + +__initcall (cap_names_export);
Quoted 20 lines · Serge E. Hallyn
Quoted 19 lines · KaiGai Kohei
This patch enables to export the code/name pairs of capabilities under /capability of securityfs.
In the current libcap, it obtains the list of capabilities from header file on the build environment statically. However, it is not enough portable between different versions of kernels, because an already built libcap cannot have knowledge about new added capabilities.
Dynamic collection of code/name pairs of capabilities will resolve this matter.
But it is not perfect one. I have a bit concern about this patch now.
1. I want to generate
cap_entriesarray fromlinux/capability.hautomatically. Is there any good idea?
2. We have to mount securityfs explicitly, or using/etc/fstab. It can make a matter when we want to use this features in very early boot sequence.
Quoted 3 lines
Quoted 1 line
Any comment please.
I like the idea, but
- snip -
Quoted 8 lines
Quoted 8 lines
kernel/capability.c +8
-0+/* +* capability code/name pairs are exported under /sys/security/capability/ +*/ +struct cap_entry_data { +unsigned int code; +const char *name; +}; +
Quoted 8 lines
kernel/capability.c int capable(int cap) · line 268
Quoted 8 lines
kernel/capability.c +8
-0+static struct cap_entry_data cap_entries[] = { +/* max number of supported format */ + { _LINUX_CAPABILITY_VERSION,"version" }, +/* max number of capability */ + {CAP_LAST_CAP ,"index" }, +/* list of capabilities */ + {CAP_CHOWN ,"cap_chown" }, + {CAP_DAC_OVERRIDE ,"cap_dac_override" },
- snip -
Quoted 8 lines
kernel/capability.c int capable(int cap) · line 302
Quoted 4 lines
kernel/capability.c +4
-0+ { CAP_MAC_OVERRIDE, "cap_mac_override" }, + { CAP_MAC_ADMIN, "cap_mac_admin" }, + { -1, NULL}, +};I don't like this duplication with the list in
include/linux/capability.h. Now when a new cap is added, it needs to be
Quoted 6 lines
1. added to
capability.h
2. swapped as the newCAP_LAST_CAPincapability.h
3. added to this list...Could you integrate the two lists (not sure how offhand), or at least put them in the same place?
The following script will generate cap_entries[] array.
cat include/linux/capability.h \
| egrep '^#define[ \t]+CAP_[A-Z_]+[ \t]+[0-9]+$' \
| awk '{ printf("\t{ %s, \"\" },\n", $2, tolower($2)); }'
It is nice to include the result of this script, like as:
static struct cap_entry_data cap_entries[] = {
/* max number of supported format */
{ _LINUX_CAPABILITY_VERSION, "version" },
/* max number of capability */
{ CAP_LAST_CAP, "index" },
#include "capability_names.h"
{ -1, NULL },
};I guess we can put this script on Makefile like as kernel/timeconst.pl doing.
Thanks,
Signature · 2 lines
OSS Platform Development Division, NEC KaiGai Kohei <[email protected]>
The attached patch enables to export capability code/name pairs under /capability of securityfs (revision 2).
Inprovements from the first revison:
- simple_read_from_buffer() is used for read method.
- cap_entries[] array is generated from include/linux/capability.h automatically.
Remaining issues:
- We have to mount securityfs explicitly, or use /etc/fstab. It can cause a matter when we want to use this feature on very early phase on boot. (like /sbin/init)
It was also concerned at the past.
http://marc.info/?l=linux-kernel&m=112063963623190&w=2
How do you think an idea that the root of securityfs is mounted on kernel/security of sysfs when it is initialized?
If securityfs got being available when kernel initializing process, we can always use this feature and the matter will be resolved.
Quoted 8 lines
Quoted 8 lines
Review
Quoted 8 lines
(quoted diff) +8
-0+static struct cap_entry_data cap_entries[] = { + /* max number of supported format */ + { _LINUX_CAPABILITY_VERSION, "version" }, + /* max number of capability */ + { CAP_LAST_CAP, "index" }, + /* list of capabilities */ + { CAP_CHOWN, "cap_chown" }, + { CAP_DAC_OVERRIDE, "cap_dac_override" },
Quoted 16 lines
- snip -
Quoted 15 lines
Review
Quoted 4 lines
(quoted diff) +4
-0+ { CAP_MAC_OVERRIDE, "cap_mac_override" }, + { CAP_MAC_ADMIN, "cap_mac_admin" }, + { -1, NULL}, +};I don't like this duplication with the list in
include/linux/capability.h.
Now when a new cap is added, it needs to be1. added to
capability.h
2. swapped as the newCAP_LAST_CAPincapability.h
3. added to this list...Could you integrate the two lists (not sure how offhand), or at least put them in the same place?
kernel/cap_names.sh generates the body of cap_entries[] array, and it is invoked when we make the kernel.
--- Makefile | 9 +++++++ cap_names.sh | 21 ++++++++++++++++ capability.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+)
kernel/Makefile +9 -0
@@ -80,3 +80,12 @@ quiet_cmd_ikconfiggz = IKCFG $@ targets += config_data.h $(obj)/config_data.h: $(obj)/config_data.gz FORCE $(call if_changed,ikconfiggz) + +# 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)/cap_names.sh > $@ +targets += cap_names.h +$(obj)/cap_names.h: $(src)/cap_names.sh $(src)/../include/linux/capability.h FORCE + $(call if_changed,cap_names)
kernel/cap_names.sh +21 -0
@@ -0,0 +1,21 @@ +#!/bin/sh + +# +# generate a cap_names.h file from include/linux/capability.h +# + +BASEDIR=`dirname $0` + +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("\t{ %s, \"%s\" },\n", $2, tolower($2)); + } + END { + printf("\t{ %u, \"index\" },\n", max_code); + }'
kernel/capability.c +75 -0
78 lines not on this page · raw message
Signature · 2 lines
OSS Platform Development Division, NEC KaiGai Kohei <[email protected]>
kernel/capability.c int capable(int cap) · line 278
Quoted 4 lines · KaiGai Kohei
kernel/capability.c +4
-0+snprintf (tmp,sizeof (tmp), + cap_entry == &cap_entries[0 ] ?"0x%08x" :"%u" , + cap_entry->code); + len =strlen (tmp);
You don't need to call strlen(), just use scnprintf() and grab the return value.
- James
Signature · 2 lines
James Morris <[email protected]>
Quoted 8 lines · James Morris
kernel/capability.c int capable(int cap) · line 278
Quoted 4 lines · KaiGai Kohei
kernel/capability.c +4
-0+snprintf (tmp,sizeof (tmp), + cap_entry == &cap_entries[0 ] ?"0x%08x" :"%u" , + cap_entry->code); + len =strlen (tmp);You don't need to call
strlen(), just usescnprintf()and grab the return value.
Thanks for your suggestion,
I'll fix it on the next posting.
Signature · 2 lines
OSS Platform Development Division, NEC KaiGai Kohei <[email protected]>
Quoted 4 lines · KaiGai Kohei
Remaining issues:
- We have to mount securityfs explicitly, or use/etc/fstab. It can cause a matter when we want to use this feature on very early phase on boot. (like/sbin/init)
Why can't early userspace itself mount securityfs?
I'm not even sure this is a good idea at all. Existing capabilities will never disappear, and, as with syscalls, it's probably up to userland to handle new ones not existing.
In any case, some more technical issues:
Quoted 1 line
kernel/cap_names.shgenerates the body of cap_entries[] array,
This needs to be in the scripts directory.
The generated header should be made idempotent (#ifdef wrapping), and also include a warning that it is automatically generated (identifying the script which does so), and that is should not be edited.
kernel/capability.c int capable(int cap) · line 296
Quoted 2 lines
kernel/capability.c +2
-0+ d_caps =securityfs_create_dir ("capability" ,NULL ); +if (!d_caps)
Wrong way to check for error -- the function returns an ERR_PTR().
kernel/capability.c int capable(int cap) · line 304
Quoted 4 lines
kernel/capability.c +4
-0+ f_caps[i] =securityfs_create_file (cap_entries[i].name,0444 , + d_caps, &cap_entries[i], + &cap_entry_fops); +if (!f_caps[i])
Ditto.
Another issue is that securityfs depends on CONFIG_SECURITY, which might be undesirable, given that capabilities are a standard feature.
- James
Signature · 2 lines
James Morris <[email protected]>
Quoted 8 lines · James Morris
Quoted 4 lines · KaiGai Kohei
Remaining issues:
- We have to mount securityfs explicitly, or use/etc/fstab. It can cause a matter when we want to use this feature on very early phase on boot. (like/sbin/init)Why can't early userspace itself mount securityfs?
Hmm,,,
It might be possible as load_policy() doing, if necessary. Please forget the previous my opinion.
Quoted 1 line
I'm not even sure this is a good idea at all. Existing capabilities will never disappear, and, as with syscalls, it's probably up to userland to handle new ones not existing.
When we use libcap built on older kernel for newer kernel, libcap cannot handle newly added capabilities, because it is not exist on the build environment. Therefore, any available capabilities should be exported dynamically by the kernel.
Quoted 5 lines
In any case, some more technical issues:
Quoted 1 line
kernel/cap_names.shgenerates the body of cap_entries[] array,This needs to be in the scripts directory.
OK, it will be moved.
Quoted 7 lines
The generated header should be made idempotent (#ifdef wrapping), and also include a warning that it is automatically generated (identifying the script which does so), and that is should not be edited.
kernel/capability.c int capable(int cap) · line 296
Quoted 2 lines
kernel/capability.c +2
-0+ d_caps =securityfs_create_dir ("capability" ,NULL ); +if (!d_caps)Wrong way to check for error -- the function returns an
ERR_PTR().
Quoted 6 lines
kernel/capability.c int capable(int cap) · line 304
Quoted 4 lines
kernel/capability.c +4
-0+ f_caps[i] =securityfs_create_file (cap_entries[i].name,0444 , + d_caps, &cap_entries[i], + &cap_entry_fops); +if (!f_caps[i])Ditto.
OK,
Quoted 1 line
Another issue is that securityfs depends on
CONFIG_SECURITY, which might be undesirable, given that capabilities are a standard feature.
We can implement this feature on another pseudo filesystems. Do you think what filesystem is the best candidate? I prefer procfs or sysfs instead.
Thanks,
Signature · 1 line
KaiGai Kohei <[email protected]>
Quoted 6 lines · KaiGai Kohei
Quoted 2 lines
Another issue is that securityfs depends on
CONFIG_SECURITY, which might be undesirable, given that capabilities are a standard feature.We can implement this feature on another pseudo filesystems. Do you think what filesystem is the best candidate? I prefer procfs or sysfs instead.
Sysfs makes more sense, as this information is system-wide and does not relate to specific processes.
Signature · 2 lines
James Morris <[email protected]>
Quoted 10 lines · James Morris
Quoted 5 lines · KaiGai Kohei
Quoted 2 lines
Another issue is that securityfs depends on
CONFIG_SECURITY, which might be undesirable, given that capabilities are a standard feature.We can implement this feature on another pseudo filesystems. Do you think what filesystem is the best candidate? I prefer procfs or sysfs instead.
Sysfs makes more sense, as this information is system-wide and does not relate to specific processes.
The following patch enables to export any capabilities which are supported on the working kernel, under the /sys/kernel/capability.
You can obtain the code/name pairs of capabilities with scanning this directory.
--
kernel/Makefile | 9 +++++++++ kernel/capability.c | 36 ++++++++++++++++++++++++++++++++++++ scripts/mkcapnames.sh | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 0 deletions(-)
kernel/Makefile +9 -0
@@ -80,3 +80,12 @@ quiet_cmd_ikconfiggz = IKCFG $@ targets += config_data.h $(obj)/config_data.h: $(obj)/config_data.gz FORCE $(call if_changed,ikconfiggz) + +# 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)
kernel/capability.c +36 -0
@@ -245,3 +245,39 @@ int capable(int cap)return __capable (current, cap); }EXPORT_SYMBOL (capable); + +/* +* Export the list of capabilities on /sys/kernel/capability +*/ +#define SYSFS_CAPABILITY_ENTRY (_name, _fmt, ...) \ + static ssize_t _name##_show(struct kset *kset, char *buffer) \ + { \ + return scnprintf(buffer, PAGE_SIZE, _fmt, __VA_ARGS__); \ + } \ + static struct subsys_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_subsys.kobj, + &capability_attr_group); +if (rc) { +printk (KERN_ERR "Unable to export capabilities\n" ); +return rc; + } + +return 0 ; +} +__initcall (capability_export_names);
scripts/mkcapnames.sh +45 -0
45 lines not on this page · raw message
Quoted 9 lines · On Fri, 28 Dec 2007 15:16:35 +0900 KaiGai Kohei wrote:
kernel/cap_names.shgenerates the body of cap_entries[] array, and it is invoked when we make the kernel.Signed-off-by KaiGai Kohei <[email protected]>--- Makefile | 9 +++++++ cap_names.sh | 21 ++++++++++++++++ capability.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+)
Hi,
Please use "diffstat -p 1 -w 70" as suggested in Documentation/SubmittingPatches so that we can know what subdirectories those listed file are actually in.
---
~Randy
desserts: http://www.xenotime.net/linux/recipes/
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 4 lines · KaiGai Kohei
Remaining issues:
- We have to mount securityfs explicitly, or use/etc/fstab. It can cause a matter when we want to use this feature on very early phase on boot. (like/sbin/init)
I'm not altogether clear how you intend this to work.
Are you saying that some future version of libcap will require that securityfs be mounted before it (libcap) will work?
Thanks
Andrew
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFHd8dE+bHCR3gb8jsRAurnAJ4t5GKckQVj4Xr1JeTjoowUniU2jACgr5V8 3D3zbx5PkrVTRaYay6ZwJSc=
=D2ZM
-----END PGP SIGNATURE-----
Quoted 9 lines · Andrew Morgan
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1Quoted 4 lines · KaiGai Kohei
Remaining issues:
- We have to mount securityfs explicitly, or use/etc/fstab. It can cause a matter when we want to use this feature on very early phase on boot. (like/sbin/init)
Quoted 4 lines
I'm not altogether clear how you intend this to work.
Are you saying that some future version of libcap will require that securityfs be mounted before it (libcap) will work?
Yes, but implementing this feature on securityfs might be not good idea as as James said. If this feature is on procfs or sysfs, it is not necessary to mount securityfs explicitly.
Thanks,
Signature · 1 line
KaiGai Kohei <[email protected]>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
There is also the issue of compiled code which explicitly raises and lowers capabilities around critical code sections (ie., as they were intended to be used) is also not well served by this change.
That is, unless the code was compiled with things like CAP_MAC_ADMIN being #define'd then it won't be able to do things like cap_set_flag() appropriately.
Cheers
Andrew
Quoted 11 lines · KaiGai Kohei
Quoted 10 lines · Andrew Morgan
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1Quoted 4 lines · KaiGai Kohei
Remaining issues:
- We have to mount securityfs explicitly, or use/etc/fstab. It can cause a matter when we want to use this feature on very early phase on boot. (like/sbin/init)I'm not altogether clear how you intend this to work.
Quoted 8 lines
Quoted 2 lines
Are you saying that some future version of libcap will require that securityfs be mounted before it (libcap) will work?
Yes, but implementing this feature on securityfs might be not good idea as as James said. If this feature is on procfs or sysfs, it is not necessary to mount securityfs explicitly.
Thanks,
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFHfD7n+bHCR3gb8jsRAsgcAKDY6qXBR3JV2addHUg5sxyZHJEkDQCfdLOL zJlf3T4SQsUNENr3kwR5pr8=
=v8C5
-----END PGP SIGNATURE-----
Quoted 7 lines
There is also the issue of compiled code which explicitly raises and lowers capabilities around critical code sections (ie., as they were intended to be used) is also not well served by this change.
That is, unless the code was compiled with things like
CAP_MAC_ADMINbeing #define'd then it won't be able to do things likecap_set_flag()appropriately.
A new function will be necessary, like:
cap_value_t cap_get_value_by_name(const char *cap_name);
If a program tries to use specific capabilities explicitly, it can apply pre-defined capability code like CAP_MAC_ADMIN.
However, when we implement a program which can deal with arbitrary capabilities, it should obtain codes of them dynamically, because it enables to work itself on the feature kernel.
Thanks,
Quoted 33 lines
Cheers
Andrew
Quoted 11 lines · KaiGai Kohei
Quoted 10 lines · Andrew Morgan
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1Quoted 4 lines · KaiGai Kohei
Remaining issues:
- We have to mount securityfs explicitly, or use/etc/fstab. It can cause a matter when we want to use this feature on very early phase on boot. (like/sbin/init)I'm not altogether clear how you intend this to work.
Quoted 7 lines
Quoted 2 lines
Are you saying that some future version of libcap will require that securityfs be mounted before it (libcap) will work?
Yes, but implementing this feature on securityfs might be not good idea as as James said. If this feature is on procfs or sysfs, it is not necessary to mount securityfs explicitly.
Thanks,
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.orgiD8DBQFHfD7n+bHCR3gb8jsRAsgcAKDY6qXBR3JV2addHUg5sxyZHJEkDQCfdLOL zJlf3T4SQsUNENr3kwR5pr8=
=v8C5
-----END PGP SIGNATURE-----