[PATCH 1/3] exporting capability code/name pairs (try 2nd) - Kernel

This is a discussion on [PATCH 1/3] exporting capability code/name pairs (try 2nd) - Kernel ; On Fri, Feb 15, 2008 at 12:38:02PM -0600, Serge E. Hallyn wrote: > Quoting Kohei KaiGai (kaigai@ak.jp.nec.com): > > Li Zefan wrote: > > - snip - > > >> +error1: > > >> + kobject_put(capability_kobj); > > >> +error0: ...

+ Reply to Thread
Page 2 of 2 FirstFirst 1 2
Results 21 to 34 of 34

Thread: [PATCH 1/3] exporting capability code/name pairs (try 2nd)

  1. Re: [PATCH] exporting capability code/name pairs (try #5.1)

    On Fri, Feb 15, 2008 at 12:38:02PM -0600, Serge E. Hallyn wrote:
    > Quoting Kohei KaiGai (kaigai@ak.jp.nec.com):
    > > Li Zefan wrote:
    > > - snip -
    > > >> +error1:
    > > >> + kobject_put(capability_kobj);
    > > >> +error0:
    > > >> + printk(KERN_ERR "Unable to export capabilities\n");
    > > >> +
    > > >> + return 0;
    > > >
    > > > Should return -EFXXX ..

    > >
    > > Oops,
    > > I fixed it as follows. Thanks for your pointed out.
    > >
    > > --------
    > > This patch enables to export code/name of capabilities supported
    > > on the running kernel.
    > >
    > > A newer kernel sometimes adds new capabilities, like CAP_MAC_ADMIN
    > > at 2.6.25. However, we have no interface to disclose what capabilities
    > > are supported on this kernel. Thus, we have to maintain libcap version
    > > in appropriate one synchronously.
    > >
    > > This patch enables libcap to collect the list of capabilities on
    > > run time, and provide them for users.
    > > It helps to improve portability of library.
    > >
    > > It exports these information as regular files under /sys/kernel/capability.
    > > The numeric node exports its name, the symbolic node exports its code.
    > >
    > > Please consider to put this patch on the queue of 2.6.25.

    >
    > Looks good, except don't you need to put the code in commoncap.c under a
    > #ifdef SYSFS?
    >
    > thanks,
    > -serge
    >
    > >
    > > Thanks,
    > > ================================================== =
    > > [kaigai@saba ~]$ ls -R /sys/kernel/capability/
    > > /sys/kernel/capability/:
    > > codes names version
    > >
    > > /sys/kernel/capability/codes:
    > > 0 10 12 14 16 18 2 21 23 25 27 29 30 32 4 6 8
    > > 1 11 13 15 17 19 20 22 24 26 28 3 31 33 5 7 9
    > >
    > > /sys/kernel/capability/names:
    > > cap_audit_control cap_kill cap_net_raw cap_sys_nice
    > > cap_audit_write cap_lease cap_setfcap cap_sys_pacct
    > > cap_chown cap_linux_immutable cap_setgid cap_sys_ptrace
    > > cap_dac_override cap_mac_admin cap_setpcap cap_sys_rawio
    > > cap_dac_read_search cap_mac_override cap_setuid cap_sys_resource
    > > cap_fowner cap_mknod cap_sys_admin cap_sys_time
    > > cap_fsetid cap_net_admin cap_sys_boot cap_sys_tty_config
    > > cap_ipc_lock cap_net_bind_service cap_sys_chroot
    > > cap_ipc_owner cap_net_broadcast cap_sys_module
    > > [kaigai@saba ~]$ cat /sys/kernel/capability/version
    > > 0x20071026
    > > [kaigai@saba ~]$ cat /sys/kernel/capability/codes/30
    > > cap_audit_control
    > > [kaigai@saba ~]$ cat /sys/kernel/capability/names/cap_sys_pacct
    > > 20
    > > [kaigai@saba ~]$
    > > ================================================== =


    As you are adding new sysfs entries, please also add the needed
    Documentation/ABI/ entries as well.

    Also, this code can be cleaned up a lot by just using the basic kobject
    attributes, and not rolling your own types here.

    thanks,

    greg k-h
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. Re: [PATCH] exporting capability code/name pairs (try #5.1)

    Greg KH wrote:
    > On Fri, Feb 15, 2008 at 12:38:02PM -0600, Serge E. Hallyn wrote:
    >>> --------
    >>> This patch enables to export code/name of capabilities supported
    >>> on the running kernel.
    >>>
    >>> A newer kernel sometimes adds new capabilities, like CAP_MAC_ADMIN
    >>> at 2.6.25. However, we have no interface to disclose what capabilities
    >>> are supported on this kernel. Thus, we have to maintain libcap version
    >>> in appropriate one synchronously.
    >>>
    >>> This patch enables libcap to collect the list of capabilities on
    >>> run time, and provide them for users.
    >>> It helps to improve portability of library.
    >>>
    >>> It exports these information as regular files under /sys/kernel/capability.
    >>> The numeric node exports its name, the symbolic node exports its code.
    >>>
    >>> Please consider to put this patch on the queue of 2.6.25.

    >> Looks good, except don't you need to put the code in commoncap.c under a
    >> #ifdef SYSFS?


    Fair enough.
    I added the #ifdef - #endif block in this patch.

    >>> ================================================== =
    >>> [kaigai@saba ~]$ ls -R /sys/kernel/capability/
    >>> /sys/kernel/capability/:
    >>> codes names version
    >>>
    >>> /sys/kernel/capability/codes:
    >>> 0 10 12 14 16 18 2 21 23 25 27 29 30 32 4 6 8
    >>> 1 11 13 15 17 19 20 22 24 26 28 3 31 33 5 7 9
    >>>
    >>> /sys/kernel/capability/names:
    >>> cap_audit_control cap_kill cap_net_raw cap_sys_nice
    >>> cap_audit_write cap_lease cap_setfcap cap_sys_pacct
    >>> cap_chown cap_linux_immutable cap_setgid cap_sys_ptrace
    >>> cap_dac_override cap_mac_admin cap_setpcap cap_sys_rawio
    >>> cap_dac_read_search cap_mac_override cap_setuid cap_sys_resource
    >>> cap_fowner cap_mknod cap_sys_admin cap_sys_time
    >>> cap_fsetid cap_net_admin cap_sys_boot cap_sys_tty_config
    >>> cap_ipc_lock cap_net_bind_service cap_sys_chroot
    >>> cap_ipc_owner cap_net_broadcast cap_sys_module
    >>> [kaigai@saba ~]$ cat /sys/kernel/capability/version
    >>> 0x20071026
    >>> [kaigai@saba ~]$ cat /sys/kernel/capability/codes/30
    >>> cap_audit_control
    >>> [kaigai@saba ~]$ cat /sys/kernel/capability/names/cap_sys_pacct
    >>> 20
    >>> [kaigai@saba ~]$
    >>> ================================================== =

    >
    > As you are adding new sysfs entries, please also add the needed
    > Documentation/ABI/ entries as well.


    OK, I'll add a short description at Documentation/ABI/sysfs-kernel-capability .

    > Also, this code can be cleaned up a lot by just using the basic kobject
    > attributes, and not rolling your own types here.


    I replaced my own defined capability_attribute by kobj_attribute.

    It made the patch cleaned up, however, it also impossible to share a single
    _show() method instance, because kobj_attribute does not have any private member.
    Is there any reason why kobj_attribute does not have "void *private;"?

    Thanks,
    Signed-off-by: KaiGai Kohei
    --
    Documentation/ABI/testing/sysfs-kernel-capability | 23 +++++
    scripts/mkcapnames.sh | 44 +++++++++
    security/Makefile | 9 ++
    security/commoncap.c | 102 +++++++++++++++++++++
    4 files changed, 178 insertions(+), 0 deletions(-)

    diff --git a/Documentation/ABI/testing/sysfs-kernel-capability b/Documentation/ABI/testing/sysfs-kernel-capability
    index e69de29..402ef06 100644
    --- a/Documentation/ABI/testing/sysfs-kernel-capability
    +++ b/Documentation/ABI/testing/sysfs-kernel-capability
    @@ -0,0 +1,23 @@
    +What: /sys/kernel/capability
    +Date: Feb 2008
    +Contact: KaiGai Kohei
    +Description:
    + The entries under /sys/kernel/capability are used to export
    + the list of capabilities the running kernel supported.
    +
    + - /sys/kernel/capability/version
    + returns the most preferable version number for the
    + running kernel.
    + e.g) $ cat /sys/kernel/capability/version
    + 0x20071026
    +
    + - /sys/kernel/capability/code/
    + returns its symbolic representation, on reading.
    + e.g) $ cat /sys/kernel/capability/codes/30
    + cap_audit_control
    +
    + - /sys/kernel/capability/name/
    + returns its numerical representation, on reading.
    + e.g) $ cat /sys/kernel/capability/names/cap_sys_pacct
    + 20
    +
    diff --git a/scripts/mkcapnames.sh b/scripts/mkcapnames.sh
    index e69de29..5d36d52 100644
    --- a/scripts/mkcapnames.sh
    +++ b/scripts/mkcapnames.sh
    @@ -0,0 +1,44 @@
    +#!/bin/sh
    +
    +#
    +# generate a cap_names.h file from include/linux/capability.h
    +#
    +
    +CAPHEAD="`dirname $0`/../include/linux/capability.h"
    +REGEXP='^#define CAP_[A-Z_]+[ ]+[0-9]+$'
    +NUMCAP=`cat "$CAPHEAD" | egrep -c "$REGEXP"`
    +
    +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 '#if !defined(SYSFS_CAP_NAME_ENTRY) || !defined(SYSFS_CAP_CODE_ENTRY)'
    +echo '#error cap_names.h should be included from security/capability.c'
    +echo '#else'
    +echo "#if $NUMCAP != CAP_LAST_CAP + 1"
    +echo '#error mkcapnames.sh cannot collect capabilities correctly'
    +echo '#else'
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("SYSFS_CAP_NAME_ENTRY(%s,%s);\n", tolower($2), $2); }'
    +echo
    +echo 'static struct attribute *capability_name_attrs[] = {'
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("\t&%s_name_attr.attr,\n", tolower($2)); } END { print "\tNULL," }'
    +echo '};'
    +
    +echo
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("SYSFS_CAP_CODE_ENTRY(%s,%s);\n", tolower($2), $2); }'
    +echo
    +echo 'static struct attribute *capability_code_attrs[] = {'
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("\t&%s_code_attr.attr,\n", tolower($2)); } END { print "\tNULL," }'
    +echo '};'
    +
    +echo '#endif'
    +echo '#endif'
    +echo '#endif'
    diff --git a/security/Makefile b/security/Makefile
    index 9e8b025..c1ffc00 100644
    --- a/security/Makefile
    +++ b/security/Makefile
    @@ -18,3 +18,12 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
    obj-$(CONFIG_SECURITY_SMACK) += commoncap.o smack/built-in.o
    obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
    obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
    +
    +# cap_names.h contains the code/name pair of capabilities.
    +# It is generated using include/linux/capability.h automatically.
    +$(obj)/commoncap.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)
    diff --git a/security/commoncap.c b/security/commoncap.c
    index 5aba826..0f2f778 100644
    --- a/security/commoncap.c
    +++ b/security/commoncap.c
    @@ -24,6 +24,8 @@
    #include
    #include
    #include
    +#include
    +#include

    /* Global security state */

    @@ -637,3 +639,103 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
    return __vm_enough_memory(mm, pages, cap_sys_admin);
    }

    +#ifdef CONFIG_SYSFS
    +/*
    + * Export the list of capabilities on /sys/kernel/capability
    + */
    +static struct kobject *capability_kobj;
    +
    +#define SYSFS_CAP_NAME_ENTRY(_name,_code) \
    + static ssize_t capname_##_name##_show(struct kobject *kobj, \
    + struct kobj_attribute *attr, \
    + char *buffer) \
    + { \
    + return scnprintf(buffer, PAGE_SIZE, "%d\n", _code); \
    + } \
    + static struct kobj_attribute _name##_name_attr = { \
    + .attr = { .name = __stringify(_name), .mode = 0444, }, \
    + .show = capname_##_name##_show, \
    + }
    +
    +#define SYSFS_CAP_CODE_ENTRY(_name,_code) \
    + static ssize_t capcode_##_name##_show(struct kobject *kobj, \
    + struct kobj_attribute *attr, \
    + char *buffer) \
    + { \
    + return scnprintf(buffer, PAGE_SIZE, "%s\n", __stringify(_name)); \
    + } \
    + static struct kobj_attribute _name##_code_attr = { \
    + .attr = { .name = __stringify(_code), .mode = 0444, }, \
    + .show = capcode_##_name##_show, \
    + }
    +
    +/*
    + * 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_name_attr_group = {
    + .name = "names",
    + .attrs = capability_name_attrs,
    +};
    +
    +static struct attribute_group capability_code_attr_group = {
    + .name = "codes",
    + .attrs = capability_code_attrs,
    +};
    +
    +static ssize_t capability_version_show(struct kobject *kobj,
    + struct kobj_attribute *attr,
    + char *buffer)
    +{
    + return scnprintf(buffer, PAGE_SIZE, "0x%08x\n",
    + _LINUX_CAPABILITY_VERSION);
    +}
    +static struct kobj_attribute cap_version_attr = {
    + .attr = { .name = "version", .mode = 0444 },
    + .show = capability_version_show,
    +};
    +
    +static int __init capability_export_names(void)
    +{
    + int rc = -ENOMEM;
    +
    + /* make /sys/kernel/capability */
    + capability_kobj = kobject_create_and_add("capability", kernel_kobj);
    + if (!capability_kobj)
    + goto error0;
    +
    + /* make /sys/kernel/capability/names */
    + rc = sysfs_create_group(capability_kobj,
    + &capability_name_attr_group);
    + if (rc)
    + goto error1;
    +
    + /* make /sys/kernel/capability/codes */
    + rc = sysfs_create_group(capability_kobj,
    + &capability_code_attr_group);
    + if (rc)
    + goto error2;
    +
    + /* make /sys/kernel/capability/version */
    + rc = sysfs_create_file(capability_kobj,
    + &cap_version_attr.attr);
    + if (rc)
    + goto error3;
    +
    + return 0;
    +
    +error3:
    + sysfs_remove_group(capability_kobj, &capability_code_attr_group);
    +error2:
    + sysfs_remove_group(capability_kobj, &capability_name_attr_group);
    +error1:
    + kobject_put(capability_kobj);
    +error0:
    + printk(KERN_ERR "Unable to export capabilities\n");
    +
    + return rc;
    +}
    +__initcall(capability_export_names);
    +#endif /* CONFIG_SYSFS */

    --
    OSS Platform Development Division, NEC
    KaiGai Kohei
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. Re: [PATCH] exporting capability code/name pairs (try #5.1)

    On Mon, Feb 18, 2008 at 04:12:53PM +0900, Kohei KaiGai wrote:
    > Greg KH wrote:
    > > On Fri, Feb 15, 2008 at 12:38:02PM -0600, Serge E. Hallyn wrote:
    > >>> --------
    > >>> This patch enables to export code/name of capabilities supported
    > >>> on the running kernel.
    > >>>
    > >>> A newer kernel sometimes adds new capabilities, like CAP_MAC_ADMIN
    > >>> at 2.6.25. However, we have no interface to disclose what capabilities
    > >>> are supported on this kernel. Thus, we have to maintain libcap version
    > >>> in appropriate one synchronously.
    > >>>
    > >>> This patch enables libcap to collect the list of capabilities on
    > >>> run time, and provide them for users.
    > >>> It helps to improve portability of library.
    > >>>
    > >>> It exports these information as regular files under /sys/kernel/capability.
    > >>> The numeric node exports its name, the symbolic node exports its code.
    > >>>
    > >>> Please consider to put this patch on the queue of 2.6.25.
    > >> Looks good, except don't you need to put the code in commoncap.c under a
    > >> #ifdef SYSFS?

    >
    > Fair enough.
    > I added the #ifdef - #endif block in this patch.


    Not needed, if SYSFS is not build in, all of that code pretty much
    compiles away to nothing. So you can drop that.

    >
    > >>> ================================================== =
    > >>> [kaigai@saba ~]$ ls -R /sys/kernel/capability/
    > >>> /sys/kernel/capability/:
    > >>> codes names version
    > >>>
    > >>> /sys/kernel/capability/codes:
    > >>> 0 10 12 14 16 18 2 21 23 25 27 29 30 32 4 6 8
    > >>> 1 11 13 15 17 19 20 22 24 26 28 3 31 33 5 7 9
    > >>>
    > >>> /sys/kernel/capability/names:
    > >>> cap_audit_control cap_kill cap_net_raw cap_sys_nice
    > >>> cap_audit_write cap_lease cap_setfcap cap_sys_pacct
    > >>> cap_chown cap_linux_immutable cap_setgid cap_sys_ptrace
    > >>> cap_dac_override cap_mac_admin cap_setpcap cap_sys_rawio
    > >>> cap_dac_read_search cap_mac_override cap_setuid cap_sys_resource
    > >>> cap_fowner cap_mknod cap_sys_admin cap_sys_time
    > >>> cap_fsetid cap_net_admin cap_sys_boot cap_sys_tty_config
    > >>> cap_ipc_lock cap_net_bind_service cap_sys_chroot
    > >>> cap_ipc_owner cap_net_broadcast cap_sys_module
    > >>> [kaigai@saba ~]$ cat /sys/kernel/capability/version
    > >>> 0x20071026
    > >>> [kaigai@saba ~]$ cat /sys/kernel/capability/codes/30
    > >>> cap_audit_control
    > >>> [kaigai@saba ~]$ cat /sys/kernel/capability/names/cap_sys_pacct
    > >>> 20
    > >>> [kaigai@saba ~]$
    > >>> ================================================== =

    > >
    > > As you are adding new sysfs entries, please also add the needed
    > > Documentation/ABI/ entries as well.

    >
    > OK, I'll add a short description at Documentation/ABI/sysfs-kernel-capability .


    Thank you.

    > > Also, this code can be cleaned up a lot by just using the basic kobject
    > > attributes, and not rolling your own types here.

    >
    > I replaced my own defined capability_attribute by kobj_attribute.
    >
    > It made the patch cleaned up, however, it also impossible to share a single
    > _show() method instance, because kobj_attribute does not have any private member.
    > Is there any reason why kobj_attribute does not have "void *private;"?


    Because no one has asked for it?

    Or you can just do as the example in samples/kobject/ does it, no need
    for the void pointer as that code shows.



    >
    > Thanks,
    > Signed-off-by: KaiGai Kohei
    > --
    > Documentation/ABI/testing/sysfs-kernel-capability | 23 +++++
    > scripts/mkcapnames.sh | 44 +++++++++
    > security/Makefile | 9 ++
    > security/commoncap.c | 102 +++++++++++++++++++++
    > 4 files changed, 178 insertions(+), 0 deletions(-)
    >
    > diff --git a/Documentation/ABI/testing/sysfs-kernel-capability b/Documentation/ABI/testing/sysfs-kernel-capability
    > index e69de29..402ef06 100644
    > --- a/Documentation/ABI/testing/sysfs-kernel-capability
    > +++ b/Documentation/ABI/testing/sysfs-kernel-capability
    > @@ -0,0 +1,23 @@
    > +What: /sys/kernel/capability
    > +Date: Feb 2008
    > +Contact: KaiGai Kohei
    > +Description:
    > + The entries under /sys/kernel/capability are used to export
    > + the list of capabilities the running kernel supported.
    > +
    > + - /sys/kernel/capability/version
    > + returns the most preferable version number for the
    > + running kernel.
    > + e.g) $ cat /sys/kernel/capability/version
    > + 0x20071026
    > +
    > + - /sys/kernel/capability/code/
    > + returns its symbolic representation, on reading.
    > + e.g) $ cat /sys/kernel/capability/codes/30
    > + cap_audit_control
    > +
    > + - /sys/kernel/capability/name/
    > + returns its numerical representation, on reading.
    > + e.g) $ cat /sys/kernel/capability/names/cap_sys_pacct
    > + 20
    > +
    > diff --git a/scripts/mkcapnames.sh b/scripts/mkcapnames.sh
    > index e69de29..5d36d52 100644
    > --- a/scripts/mkcapnames.sh
    > +++ b/scripts/mkcapnames.sh
    > @@ -0,0 +1,44 @@
    > +#!/bin/sh
    > +
    > +#
    > +# generate a cap_names.h file from include/linux/capability.h
    > +#
    > +
    > +CAPHEAD="`dirname $0`/../include/linux/capability.h"
    > +REGEXP='^#define CAP_[A-Z_]+[ ]+[0-9]+$'
    > +NUMCAP=`cat "$CAPHEAD" | egrep -c "$REGEXP"`
    > +
    > +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 '#if !defined(SYSFS_CAP_NAME_ENTRY) || !defined(SYSFS_CAP_CODE_ENTRY)'
    > +echo '#error cap_names.h should be included from security/capability.c'
    > +echo '#else'
    > +echo "#if $NUMCAP != CAP_LAST_CAP + 1"
    > +echo '#error mkcapnames.sh cannot collect capabilities correctly'
    > +echo '#else'
    > +cat "$CAPHEAD" | egrep "$REGEXP" \
    > + | awk '{ printf("SYSFS_CAP_NAME_ENTRY(%s,%s);\n", tolower($2), $2); }'
    > +echo
    > +echo 'static struct attribute *capability_name_attrs[] = {'
    > +cat "$CAPHEAD" | egrep "$REGEXP" \
    > + | awk '{ printf("\t&%s_name_attr.attr,\n", tolower($2)); } END { print "\tNULL," }'
    > +echo '};'
    > +
    > +echo
    > +cat "$CAPHEAD" | egrep "$REGEXP" \
    > + | awk '{ printf("SYSFS_CAP_CODE_ENTRY(%s,%s);\n", tolower($2), $2); }'
    > +echo
    > +echo 'static struct attribute *capability_code_attrs[] = {'
    > +cat "$CAPHEAD" | egrep "$REGEXP" \
    > + | awk '{ printf("\t&%s_code_attr.attr,\n", tolower($2)); } END { print "\tNULL," }'
    > +echo '};'
    > +
    > +echo '#endif'
    > +echo '#endif'
    > +echo '#endif'
    > diff --git a/security/Makefile b/security/Makefile
    > index 9e8b025..c1ffc00 100644
    > --- a/security/Makefile
    > +++ b/security/Makefile
    > @@ -18,3 +18,12 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
    > obj-$(CONFIG_SECURITY_SMACK) += commoncap.o smack/built-in.o
    > obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
    > obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
    > +
    > +# cap_names.h contains the code/name pair of capabilities.
    > +# It is generated using include/linux/capability.h automatically.
    > +$(obj)/commoncap.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)
    > diff --git a/security/commoncap.c b/security/commoncap.c
    > index 5aba826..0f2f778 100644
    > --- a/security/commoncap.c
    > +++ b/security/commoncap.c
    > @@ -24,6 +24,8 @@
    > #include
    > #include
    > #include
    > +#include
    > +#include
    >
    > /* Global security state */
    >
    > @@ -637,3 +639,103 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
    > return __vm_enough_memory(mm, pages, cap_sys_admin);
    > }
    >
    > +#ifdef CONFIG_SYSFS
    > +/*
    > + * Export the list of capabilities on /sys/kernel/capability
    > + */
    > +static struct kobject *capability_kobj;
    > +
    > +#define SYSFS_CAP_NAME_ENTRY(_name,_code) \
    > + static ssize_t capname_##_name##_show(struct kobject *kobj, \
    > + struct kobj_attribute *attr, \
    > + char *buffer) \
    > + { \
    > + return scnprintf(buffer, PAGE_SIZE, "%d\n", _code); \
    > + } \
    > + static struct kobj_attribute _name##_name_attr = { \
    > + .attr = { .name = __stringify(_name), .mode = 0444, }, \
    > + .show = capname_##_name##_show, \
    > + }
    > +
    > +#define SYSFS_CAP_CODE_ENTRY(_name,_code) \
    > + static ssize_t capcode_##_name##_show(struct kobject *kobj, \
    > + struct kobj_attribute *attr, \
    > + char *buffer) \
    > + { \
    > + return scnprintf(buffer, PAGE_SIZE, "%s\n", __stringify(_name)); \
    > + } \
    > + static struct kobj_attribute _name##_code_attr = { \
    > + .attr = { .name = __stringify(_code), .mode = 0444, }, \
    > + .show = capcode_##_name##_show, \
    > + }
    > +
    > +/*
    > + * 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_name_attr_group = {
    > + .name = "names",
    > + .attrs = capability_name_attrs,
    > +};
    > +
    > +static struct attribute_group capability_code_attr_group = {
    > + .name = "codes",
    > + .attrs = capability_code_attrs,
    > +};
    > +
    > +static ssize_t capability_version_show(struct kobject *kobj,
    > + struct kobj_attribute *attr,
    > + char *buffer)
    > +{
    > + return scnprintf(buffer, PAGE_SIZE, "0x%08x\n",
    > + _LINUX_CAPABILITY_VERSION);
    > +}
    > +static struct kobj_attribute cap_version_attr = {
    > + .attr = { .name = "version", .mode = 0444 },
    > + .show = capability_version_show,
    > +};


    We do have macros for these kinds of things

    Look at ATTR() and friends.

    > +
    > +static int __init capability_export_names(void)
    > +{
    > + int rc = -ENOMEM;
    > +
    > + /* make /sys/kernel/capability */
    > + capability_kobj = kobject_create_and_add("capability", kernel_kobj);
    > + if (!capability_kobj)
    > + goto error0;
    > +
    > + /* make /sys/kernel/capability/names */
    > + rc = sysfs_create_group(capability_kobj,
    > + &capability_name_attr_group);
    > + if (rc)
    > + goto error1;
    > +
    > + /* make /sys/kernel/capability/codes */
    > + rc = sysfs_create_group(capability_kobj,
    > + &capability_code_attr_group);
    > + if (rc)
    > + goto error2;
    > +
    > + /* make /sys/kernel/capability/version */
    > + rc = sysfs_create_file(capability_kobj,
    > + &cap_version_attr.attr);
    > + if (rc)
    > + goto error3;
    > +
    > + return 0;
    > +
    > +error3:
    > + sysfs_remove_group(capability_kobj, &capability_code_attr_group);
    > +error2:
    > + sysfs_remove_group(capability_kobj, &capability_name_attr_group);
    > +error1:
    > + kobject_put(capability_kobj);
    > +error0:
    > + printk(KERN_ERR "Unable to export capabilities\n");
    > +
    > + return rc;
    > +}
    > +__initcall(capability_export_names);
    > +#endif /* CONFIG_SYSFS */


    Where do you remove these files? Or will that never happen?

    thanks,

    greg k-h
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  4. Re: [PATCH] exporting capability code/name pairs (try #5.1)

    Greg KH wrote:
    > On Mon, Feb 18, 2008 at 04:12:53PM +0900, Kohei KaiGai wrote:
    >> Greg KH wrote:
    >>> On Fri, Feb 15, 2008 at 12:38:02PM -0600, Serge E. Hallyn wrote:
    >>>>> --------
    >>>>> This patch enables to export code/name of capabilities supported
    >>>>> on the running kernel.
    >>>>>
    >>>>> A newer kernel sometimes adds new capabilities, like CAP_MAC_ADMIN
    >>>>> at 2.6.25. However, we have no interface to disclose what capabilities
    >>>>> are supported on this kernel. Thus, we have to maintain libcap version
    >>>>> in appropriate one synchronously.
    >>>>>
    >>>>> This patch enables libcap to collect the list of capabilities on
    >>>>> run time, and provide them for users.
    >>>>> It helps to improve portability of library.
    >>>>>
    >>>>> It exports these information as regular files under /sys/kernel/capability.
    >>>>> The numeric node exports its name, the symbolic node exports its code.
    >>>>>
    >>>>> Please consider to put this patch on the queue of 2.6.25.
    >>>> Looks good, except don't you need to put the code in commoncap.c under a
    >>>> #ifdef SYSFS?

    >> Fair enough.
    >> I added the #ifdef - #endif block in this patch.

    >
    > Not needed, if SYSFS is not build in, all of that code pretty much
    > compiles away to nothing. So you can drop that.


    Hmm..., I reverted these #ifdef and #endif in this version.

    >>> Also, this code can be cleaned up a lot by just using the basic kobject
    >>> attributes, and not rolling your own types here.

    >> I replaced my own defined capability_attribute by kobj_attribute.
    >>
    >> It made the patch cleaned up, however, it also impossible to share a single
    >> _show() method instance, because kobj_attribute does not have any private member.
    >> Is there any reason why kobj_attribute does not have "void *private;"?

    >
    > Because no one has asked for it?
    >
    > Or you can just do as the example in samples/kobject/ does it, no need
    > for the void pointer as that code shows.


    It shows us a good example in samples/kobject.

    However, it is unsuitable to export the list of capabilities.
    The shared _show() method (b_show) calls strcmp() once with the name of kobject
    attribute to switch its returning string.
    If we have 34 of candidates to be returned, like the capability case, we have
    to call strcmp() 33 times in maximum.

    If we can have a private member in kobj_attribute, we can found the content
    to be returned in a single step.

    >> +static struct kobj_attribute cap_version_attr = {
    >> + .attr = { .name = "version", .mode = 0444 },
    >> + .show = capability_version_show,
    >> +};

    >
    > We do have macros for these kinds of things
    >
    > Look at ATTR() and friends.


    OK, fixed.
    I applied __ATTR() instead.

    >> +static int __init capability_export_names(void)
    >> +{
    >> + int rc = -ENOMEM;
    >> +
    >> + /* make /sys/kernel/capability */
    >> + capability_kobj = kobject_create_and_add("capability", kernel_kobj);
    >> + if (!capability_kobj)
    >> + goto error0;
    >> +
    >> + /* make /sys/kernel/capability/names */
    >> + rc = sysfs_create_group(capability_kobj,
    >> + &capability_name_attr_group);
    >> + if (rc)
    >> + goto error1;
    >> +
    >> + /* make /sys/kernel/capability/codes */
    >> + rc = sysfs_create_group(capability_kobj,
    >> + &capability_code_attr_group);
    >> + if (rc)
    >> + goto error2;
    >> +
    >> + /* make /sys/kernel/capability/version */
    >> + rc = sysfs_create_file(capability_kobj,
    >> + &cap_version_attr.attr);
    >> + if (rc)
    >> + goto error3;
    >> +
    >> + return 0;
    >> +
    >> +error3:
    >> + sysfs_remove_group(capability_kobj, &capability_code_attr_group);
    >> +error2:
    >> + sysfs_remove_group(capability_kobj, &capability_name_attr_group);
    >> +error1:
    >> + kobject_put(capability_kobj);
    >> +error0:
    >> + printk(KERN_ERR "Unable to export capabilities\n");
    >> +
    >> + return rc;
    >> +}
    >> +__initcall(capability_export_names);
    >> +#endif /* CONFIG_SYSFS */

    >
    > Where do you remove these files? Or will that never happen?


    Removing these files are never happen.

    Thanks,

    Signed-off-by: KaiGai Kohei
    --
    Documentation/ABI/testing/sysfs-kernel-capability | 23 +++++
    scripts/mkcapnames.sh | 44 ++++++++++
    security/Makefile | 9 ++
    security/commoncap.c | 94 +++++++++++++++++++++
    4 files changed, 170 insertions(+), 0 deletions(-)

    diff --git a/Documentation/ABI/testing/sysfs-kernel-capability b/Documentation/ABI/testing/sysfs-kernel-capability
    index e69de29..402ef06 100644
    --- a/Documentation/ABI/testing/sysfs-kernel-capability
    +++ b/Documentation/ABI/testing/sysfs-kernel-capability
    @@ -0,0 +1,23 @@
    +What: /sys/kernel/capability
    +Date: Feb 2008
    +Contact: KaiGai Kohei
    +Description:
    + The entries under /sys/kernel/capability are used to export
    + the list of capabilities the running kernel supported.
    +
    + - /sys/kernel/capability/version
    + returns the most preferable version number for the
    + running kernel.
    + e.g) $ cat /sys/kernel/capability/version
    + 0x20071026
    +
    + - /sys/kernel/capability/code/
    + returns its symbolic representation, on reading.
    + e.g) $ cat /sys/kernel/capability/codes/30
    + cap_audit_control
    +
    + - /sys/kernel/capability/name/
    + returns its numerical representation, on reading.
    + e.g) $ cat /sys/kernel/capability/names/cap_sys_pacct
    + 20
    +
    diff --git a/scripts/mkcapnames.sh b/scripts/mkcapnames.sh
    index e69de29..5d36d52 100644
    --- a/scripts/mkcapnames.sh
    +++ b/scripts/mkcapnames.sh
    @@ -0,0 +1,44 @@
    +#!/bin/sh
    +
    +#
    +# generate a cap_names.h file from include/linux/capability.h
    +#
    +
    +CAPHEAD="`dirname $0`/../include/linux/capability.h"
    +REGEXP='^#define CAP_[A-Z_]+[ ]+[0-9]+$'
    +NUMCAP=`cat "$CAPHEAD" | egrep -c "$REGEXP"`
    +
    +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 '#if !defined(SYSFS_CAP_NAME_ENTRY) || !defined(SYSFS_CAP_CODE_ENTRY)'
    +echo '#error cap_names.h should be included from security/capability.c'
    +echo '#else'
    +echo "#if $NUMCAP != CAP_LAST_CAP + 1"
    +echo '#error mkcapnames.sh cannot collect capabilities correctly'
    +echo '#else'
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("SYSFS_CAP_NAME_ENTRY(%s,%s);\n", tolower($2), $2); }'
    +echo
    +echo 'static struct attribute *capability_name_attrs[] = {'
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("\t&%s_name_attr.attr,\n", tolower($2)); } END { print "\tNULL," }'
    +echo '};'
    +
    +echo
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("SYSFS_CAP_CODE_ENTRY(%s,%s);\n", tolower($2), $2); }'
    +echo
    +echo 'static struct attribute *capability_code_attrs[] = {'
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("\t&%s_code_attr.attr,\n", tolower($2)); } END { print "\tNULL," }'
    +echo '};'
    +
    +echo '#endif'
    +echo '#endif'
    +echo '#endif'
    diff --git a/security/Makefile b/security/Makefile
    index 9e8b025..c1ffc00 100644
    --- a/security/Makefile
    +++ b/security/Makefile
    @@ -18,3 +18,12 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
    obj-$(CONFIG_SECURITY_SMACK) += commoncap.o smack/built-in.o
    obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
    obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
    +
    +# cap_names.h contains the code/name pair of capabilities.
    +# It is generated using include/linux/capability.h automatically.
    +$(obj)/commoncap.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)
    diff --git a/security/commoncap.c b/security/commoncap.c
    index 5aba826..8e8fbd9 100644
    --- a/security/commoncap.c
    +++ b/security/commoncap.c
    @@ -24,6 +24,8 @@
    #include
    #include
    #include
    +#include
    +#include

    /* Global security state */

    @@ -637,3 +639,95 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
    return __vm_enough_memory(mm, pages, cap_sys_admin);
    }

    +/*
    + * Export the list of capabilities on /sys/kernel/capability
    + */
    +static struct kobject *capability_kobj;
    +
    +#define SYSFS_CAP_NAME_ENTRY(_name,_code) \
    + static ssize_t capname_##_name##_show(struct kobject *kobj, \
    + struct kobj_attribute *attr, \
    + char *buffer) \
    + { \
    + return scnprintf(buffer, PAGE_SIZE, "%d\n", _code); \
    + } \
    + static struct kobj_attribute _name##_name_attr = \
    + __ATTR(_name, 0444, capname_##_name##_show, NULL)
    +
    +#define SYSFS_CAP_CODE_ENTRY(_name,_code) \
    + static ssize_t capcode_##_name##_show(struct kobject *kobj, \
    + struct kobj_attribute *attr, \
    + char *buffer) \
    + { \
    + return scnprintf(buffer, PAGE_SIZE, "%s\n", __stringify(_name)); \
    + } \
    + static struct kobj_attribute _name##_code_attr = \
    + __ATTR(_code, 0444, capcode_##_name##_show, NULL)
    +
    +/*
    + * 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_name_attr_group = {
    + .name = "names",
    + .attrs = capability_name_attrs,
    +};
    +
    +static struct attribute_group capability_code_attr_group = {
    + .name = "codes",
    + .attrs = capability_code_attrs,
    +};
    +
    +static ssize_t capability_version_show(struct kobject *kobj,
    + struct kobj_attribute *attr,
    + char *buffer)
    +{
    + return scnprintf(buffer, PAGE_SIZE, "0x%08x\n",
    + _LINUX_CAPABILITY_VERSION);
    +}
    +static struct kobj_attribute cap_version_attr =
    + __ATTR(version, 0444, capability_version_show, NULL);
    +
    +static int __init capability_export_names(void)
    +{
    + int rc = -ENOMEM;
    +
    + /* make /sys/kernel/capability */
    + capability_kobj = kobject_create_and_add("capability", kernel_kobj);
    + if (!capability_kobj)
    + goto error0;
    +
    + /* make /sys/kernel/capability/names */
    + rc = sysfs_create_group(capability_kobj,
    + &capability_name_attr_group);
    + if (rc)
    + goto error1;
    +
    + /* make /sys/kernel/capability/codes */
    + rc = sysfs_create_group(capability_kobj,
    + &capability_code_attr_group);
    + if (rc)
    + goto error2;
    +
    + /* make /sys/kernel/capability/version */
    + rc = sysfs_create_file(capability_kobj,
    + &cap_version_attr.attr);
    + if (rc)
    + goto error3;
    +
    + return 0;
    +
    +error3:
    + sysfs_remove_group(capability_kobj, &capability_code_attr_group);
    +error2:
    + sysfs_remove_group(capability_kobj, &capability_name_attr_group);
    +error1:
    + kobject_put(capability_kobj);
    +error0:
    + printk(KERN_ERR "Unable to export capabilities\n");
    +
    + return rc;
    +}
    +__initcall(capability_export_names);

    --
    OSS Platform Development Division, NEC
    KaiGai Kohei
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  5. Re: [PATCH] exporting capability code/name pairs (try #5.1)

    Quoting Greg KH (greg@kroah.com):
    > On Mon, Feb 18, 2008 at 04:12:53PM +0900, Kohei KaiGai wrote:
    > > Greg KH wrote:
    > > > On Fri, Feb 15, 2008 at 12:38:02PM -0600, Serge E. Hallyn wrote:
    > > >>> --------
    > > >>> This patch enables to export code/name of capabilities supported
    > > >>> on the running kernel.
    > > >>>
    > > >>> A newer kernel sometimes adds new capabilities, like CAP_MAC_ADMIN
    > > >>> at 2.6.25. However, we have no interface to disclose what capabilities
    > > >>> are supported on this kernel. Thus, we have to maintain libcap version
    > > >>> in appropriate one synchronously.
    > > >>>
    > > >>> This patch enables libcap to collect the list of capabilities on
    > > >>> run time, and provide them for users.
    > > >>> It helps to improve portability of library.
    > > >>>
    > > >>> It exports these information as regular files under /sys/kernel/capability.
    > > >>> The numeric node exports its name, the symbolic node exports its code.
    > > >>>
    > > >>> Please consider to put this patch on the queue of 2.6.25.
    > > >> Looks good, except don't you need to put the code in commoncap.c under a
    > > >> #ifdef SYSFS?

    > >
    > > Fair enough.
    > > I added the #ifdef - #endif block in this patch.

    >
    > Not needed, if SYSFS is not build in, all of that code pretty much
    > compiles away to nothing. So you can drop that.


    Oops. Sorry.

    -serge
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  6. Re: [PATCH] exporting capability code/name pairs (try #5.1)

    On Mon, Feb 18, 2008 at 05:45:46PM +0900, Kohei KaiGai wrote:
    > Greg KH wrote:
    > >>> Also, this code can be cleaned up a lot by just using the basic kobject
    > >>> attributes, and not rolling your own types here.
    > >> I replaced my own defined capability_attribute by kobj_attribute.
    > >>
    > >> It made the patch cleaned up, however, it also impossible to share a single
    > >> _show() method instance, because kobj_attribute does not have any private member.
    > >> Is there any reason why kobj_attribute does not have "void *private;"?

    > >
    > > Because no one has asked for it?
    > >
    > > Or you can just do as the example in samples/kobject/ does it, no need
    > > for the void pointer as that code shows.

    >
    > It shows us a good example in samples/kobject.
    >
    > However, it is unsuitable to export the list of capabilities.
    > The shared _show() method (b_show) calls strcmp() once with the name of kobject
    > attribute to switch its returning string.
    > If we have 34 of candidates to be returned, like the capability case, we have
    > to call strcmp() 33 times in maximum.
    >
    > If we can have a private member in kobj_attribute, we can found the content
    > to be returned in a single step.


    Ok, again, just send me a patch that adds this functionality and we will
    be very glad to consider it.

    thnaks,

    greg k-h
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  7. [PATCH] exporting capability code/name pairs (try #6)

    Greg KH wrote:
    > On Mon, Feb 18, 2008 at 05:45:46PM +0900, Kohei KaiGai wrote:
    >> Greg KH wrote:
    >>>>> Also, this code can be cleaned up a lot by just using the basic kobject
    >>>>> attributes, and not rolling your own types here.
    >>>> I replaced my own defined capability_attribute by kobj_attribute.
    >>>>
    >>>> It made the patch cleaned up, however, it also impossible to share a single
    >>>> _show() method instance, because kobj_attribute does not have any private member.
    >>>> Is there any reason why kobj_attribute does not have "void *private;"?
    >>> Because no one has asked for it?
    >>>
    >>> Or you can just do as the example in samples/kobject/ does it, no need
    >>> for the void pointer as that code shows.

    >> It shows us a good example in samples/kobject.
    >>
    >> However, it is unsuitable to export the list of capabilities.
    >> The shared _show() method (b_show) calls strcmp() once with the name of kobject
    >> attribute to switch its returning string.
    >> If we have 34 of candidates to be returned, like the capability case, we have
    >> to call strcmp() 33 times in maximum.
    >>
    >> If we can have a private member in kobj_attribute, we can found the content
    >> to be returned in a single step.

    >
    > Ok, again, just send me a patch that adds this functionality and we will
    > be very glad to consider it.


    In the attached patch, every attribute entry stores its capability
    identifier in numerical or symbolic representation within private
    data field of kobj_attribute structure.
    The rest of them are unchanged.

    ----
    [2/2] Exporting capability code/name pairs

    This patch enables to export code/name of capabilities supported
    on the running kernel.

    A newer kernel sometimes adds new capabilities, like CAP_MAC_ADMIN
    at 2.6.25. However, we have no interface to disclose what capabilities
    are supported on this kernel. Thus, we have to maintain libcap version
    in appropriate one synchronously.

    This patch enables libcap to collect the list of capabilities on
    run time, and provide them for users.
    It helps to improve portability of library.

    It exports these information as regular files under /sys/kernel/capability.
    The numeric node exports its name, the symbolic node exports its code.

    Please consider to put this patch on the queue of 2.6.25.

    Thanks,
    ================================================== =
    [kaigai@saba ~]$ ls -R /sys/kernel/capability/
    /sys/kernel/capability/:
    codes names version

    /sys/kernel/capability/codes:
    0 10 12 14 16 18 2 21 23 25 27 29 30 32 4 6 8
    1 11 13 15 17 19 20 22 24 26 28 3 31 33 5 7 9

    /sys/kernel/capability/names:
    cap_audit_control cap_kill cap_net_raw cap_sys_nice
    cap_audit_write cap_lease cap_setfcap cap_sys_pacct
    cap_chown cap_linux_immutable cap_setgid cap_sys_ptrace
    cap_dac_override cap_mac_admin cap_setpcap cap_sys_rawio
    cap_dac_read_search cap_mac_override cap_setuid cap_sys_resource
    cap_fowner cap_mknod cap_sys_admin cap_sys_time
    cap_fsetid cap_net_admin cap_sys_boot cap_sys_tty_config
    cap_ipc_lock cap_net_bind_service cap_sys_chroot
    cap_ipc_owner cap_net_broadcast cap_sys_module
    [kaigai@saba ~]$ cat /sys/kernel/capability/version
    0x20071026
    [kaigai@saba ~]$ cat /sys/kernel/capability/codes/30
    cap_audit_control
    [kaigai@saba ~]$ cat /sys/kernel/capability/names/cap_sys_pacct
    20
    [kaigai@saba ~]$
    ================================================== =

    Signed-off-by: KaiGai Kohei

    --
    Documentation/ABI/testing/sysfs-kernel-capability | 23 +++++
    scripts/mkcapnames.sh | 44 +++++++++
    security/Makefile | 9 ++
    security/commoncap.c | 99 +++++++++++++++++++++
    4 files changed, 175 insertions(+), 0 deletions(-)

    diff --git a/Documentation/ABI/testing/sysfs-kernel-capability b/Documentation/ABI/testing/sysfs-kernel-capability
    index e69de29..402ef06 100644
    --- a/Documentation/ABI/testing/sysfs-kernel-capability
    +++ b/Documentation/ABI/testing/sysfs-kernel-capability
    @@ -0,0 +1,23 @@
    +What: /sys/kernel/capability
    +Date: Feb 2008
    +Contact: KaiGai Kohei
    +Description:
    + The entries under /sys/kernel/capability are used to export
    + the list of capabilities the running kernel supported.
    +
    + - /sys/kernel/capability/version
    + returns the most preferable version number for the
    + running kernel.
    + e.g) $ cat /sys/kernel/capability/version
    + 0x20071026
    +
    + - /sys/kernel/capability/code/
    + returns its symbolic representation, on reading.
    + e.g) $ cat /sys/kernel/capability/codes/30
    + cap_audit_control
    +
    + - /sys/kernel/capability/name/
    + returns its numerical representation, on reading.
    + e.g) $ cat /sys/kernel/capability/names/cap_sys_pacct
    + 20
    +
    diff --git a/scripts/mkcapnames.sh b/scripts/mkcapnames.sh
    index e69de29..5d36d52 100644
    --- a/scripts/mkcapnames.sh
    +++ b/scripts/mkcapnames.sh
    @@ -0,0 +1,44 @@
    +#!/bin/sh
    +
    +#
    +# generate a cap_names.h file from include/linux/capability.h
    +#
    +
    +CAPHEAD="`dirname $0`/../include/linux/capability.h"
    +REGEXP='^#define CAP_[A-Z_]+[ ]+[0-9]+$'
    +NUMCAP=`cat "$CAPHEAD" | egrep -c "$REGEXP"`
    +
    +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 '#if !defined(SYSFS_CAP_NAME_ENTRY) || !defined(SYSFS_CAP_CODE_ENTRY)'
    +echo '#error cap_names.h should be included from security/capability.c'
    +echo '#else'
    +echo "#if $NUMCAP != CAP_LAST_CAP + 1"
    +echo '#error mkcapnames.sh cannot collect capabilities correctly'
    +echo '#else'
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("SYSFS_CAP_NAME_ENTRY(%s,%s);\n", tolower($2), $2); }'
    +echo
    +echo 'static struct attribute *capability_name_attrs[] = {'
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("\t&%s_name_attr.attr,\n", tolower($2)); } END { print "\tNULL," }'
    +echo '};'
    +
    +echo
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("SYSFS_CAP_CODE_ENTRY(%s,%s);\n", tolower($2), $2); }'
    +echo
    +echo 'static struct attribute *capability_code_attrs[] = {'
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("\t&%s_code_attr.attr,\n", tolower($2)); } END { print "\tNULL," }'
    +echo '};'
    +
    +echo '#endif'
    +echo '#endif'
    +echo '#endif'
    diff --git a/security/Makefile b/security/Makefile
    index 9e8b025..c1ffc00 100644
    --- a/security/Makefile
    +++ b/security/Makefile
    @@ -18,3 +18,12 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
    obj-$(CONFIG_SECURITY_SMACK) += commoncap.o smack/built-in.o
    obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
    obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
    +
    +# cap_names.h contains the code/name pair of capabilities.
    +# It is generated using include/linux/capability.h automatically.
    +$(obj)/commoncap.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)
    diff --git a/security/commoncap.c b/security/commoncap.c
    index 5aba826..2f3b49a 100644
    --- a/security/commoncap.c
    +++ b/security/commoncap.c
    @@ -24,6 +24,8 @@
    #include
    #include
    #include
    +#include
    +#include

    /* Global security state */

    @@ -637,3 +639,100 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
    return __vm_enough_memory(mm, pages, cap_sys_admin);
    }

    +/*
    + * Export the list of capabilities on /sys/kernel/capability
    + */
    +static struct kobject *capability_kobj;
    +
    +static ssize_t capability_name_show(struct kobject *kobj,
    + struct kobj_attribute *attr,
    + char *buffer)
    +{
    + /* It returns numerical representation of capability. */
    + return scnprintf(buffer, PAGE_SIZE, "%d\n", (int) attr->data);
    +}
    +
    +static ssize_t capability_code_show(struct kobject *kobj,
    + struct kobj_attribute *attr,
    + char *buffer)
    +{
    + /* It returns symbolic representation of capability. */
    + return scnprintf(buffer, PAGE_SIZE, "%s\n", (char *) attr->data);
    +}
    +
    +static ssize_t capability_version_show(struct kobject *kobj,
    + struct kobj_attribute *attr,
    + char *buffer)
    +{
    + return scnprintf(buffer, PAGE_SIZE, "0x%08x\n",
    + _LINUX_CAPABILITY_VERSION);
    +}
    +
    +#define SYSFS_CAP_NAME_ENTRY(_name,_code) \
    + static struct kobj_attribute _name##_name_attr = \
    + __ATTR_DATA(_name, 0444, capability_name_show, NULL, (int)(_code))
    +
    +#define SYSFS_CAP_CODE_ENTRY(_name,_code) \
    + static struct kobj_attribute _name##_code_attr = \
    + __ATTR_DATA(_code, 0444, capability_code_show, NULL, __stringify(_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_name_attr_group = {
    + .name = "names",
    + .attrs = capability_name_attrs,
    +};
    +
    +static struct attribute_group capability_code_attr_group = {
    + .name = "codes",
    + .attrs = capability_code_attrs,
    +};
    +
    +static struct kobj_attribute cap_version_attr =
    + __ATTR(version, 0444, capability_version_show, NULL);
    +
    +static int __init capability_export_names(void)
    +{
    + int rc = -ENOMEM;
    +
    + /* make /sys/kernel/capability */
    + capability_kobj = kobject_create_and_add("capability", kernel_kobj);
    + if (!capability_kobj)
    + goto error0;
    +
    + /* make /sys/kernel/capability/names */
    + rc = sysfs_create_group(capability_kobj,
    + &capability_name_attr_group);
    + if (rc)
    + goto error1;
    +
    + /* make /sys/kernel/capability/codes */
    + rc = sysfs_create_group(capability_kobj,
    + &capability_code_attr_group);
    + if (rc)
    + goto error2;
    +
    + /* make /sys/kernel/capability/version */
    + rc = sysfs_create_file(capability_kobj,
    + &cap_version_attr.attr);
    + if (rc)
    + goto error3;
    +
    + return 0;
    +
    +error3:
    + sysfs_remove_group(capability_kobj, &capability_code_attr_group);
    +error2:
    + sysfs_remove_group(capability_kobj, &capability_name_attr_group);
    +error1:
    + kobject_put(capability_kobj);
    +error0:
    + printk(KERN_ERR "Unable to export capabilities\n");
    +
    + return rc;
    +}
    +__initcall(capability_export_names);

    --
    OSS Platform Development Division, NEC
    KaiGai Kohei
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  8. [PATCH] exporting capability code/name pairs (try #6)

    >> If we can have a private member in kobj_attribute, we can found the content
    >> to be returned in a single step.

    >
    > Ok, again, just send me a patch that adds this functionality and we will
    > be very glad to consider it.


    [1/2] Add a private data field within kobj_attribute structure.

    This patch add a private data field, declared as void *, within kobj_attribute
    structure. Anyone wants to use sysfs can store their private data to refer at
    _show() and _store() method.
    It enables to share a single method function with several similar entries,
    like ones to export the list of capabilities the running kernel supported.

    Signed-off-by: KaiGai Kohei
    --
    include/linux/kobject.h | 1 +
    include/linux/sysfs.h | 7 +++++++
    2 files changed, 8 insertions(+), 0 deletions(-)

    diff --git a/include/linux/kobject.h b/include/linux/kobject.h
    index caa3f41..57d5bf1 100644
    --- a/include/linux/kobject.h
    +++ b/include/linux/kobject.h
    @@ -130,6 +130,7 @@ struct kobj_attribute {
    char *buf);
    ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
    const char *buf, size_t count);
    + void *data; /* a private field */
    };

    extern struct sysfs_ops kobj_sysfs_ops;
    diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
    index 8027104..6f40ff9 100644
    --- a/include/linux/sysfs.h
    +++ b/include/linux/sysfs.h
    @@ -50,6 +50,13 @@ struct attribute_group {
    .store = _store, \
    }

    +#define __ATTR_DATA(_name,_mode,_show,_store,_data) { \
    + .attr = {.name = __stringify(_name), .mode = _mode }, \
    + .show = _show, \
    + .store = _store, \
    + .data = (void *)(_data), \
    +}
    +
    #define __ATTR_RO(_name) { \
    .attr = { .name = __stringify(_name), .mode = 0444 }, \
    .show = _name##_show, \

    --
    OSS Platform Development Division, NEC
    KaiGai Kohei
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  9. Re: [PATCH] exporting capability code/name pairs (try #6)

    On Wed, Feb 20, 2008 at 01:38:59PM +0900, Kohei KaiGai wrote:
    > >> If we can have a private member in kobj_attribute, we can found the

    > content
    > >> to be returned in a single step.

    > >
    > > Ok, again, just send me a patch that adds this functionality and we will
    > > be very glad to consider it.

    >
    > [1/2] Add a private data field within kobj_attribute structure.
    >
    > This patch add a private data field, declared as void *, within
    > kobj_attribute
    > structure. Anyone wants to use sysfs can store their private data to refer
    > at
    > _show() and _store() method.
    > It enables to share a single method function with several similar entries,
    > like ones to export the list of capabilities the running kernel supported.


    But your patch 2/2 doesn't use this interface, why not?

    > include/linux/kobject.h | 1 +
    > include/linux/sysfs.h | 7 +++++++
    > 2 files changed, 8 insertions(+), 0 deletions(-)
    >
    > diff --git a/include/linux/kobject.h b/include/linux/kobject.h
    > index caa3f41..57d5bf1 100644
    > --- a/include/linux/kobject.h
    > +++ b/include/linux/kobject.h
    > @@ -130,6 +130,7 @@ struct kobj_attribute {
    > char *buf);
    > ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
    > const char *buf, size_t count);
    > + void *data; /* a private field */


    Hm, can you really use this?

    > extern struct sysfs_ops kobj_sysfs_ops;
    > diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
    > index 8027104..6f40ff9 100644
    > --- a/include/linux/sysfs.h
    > +++ b/include/linux/sysfs.h
    > @@ -50,6 +50,13 @@ struct attribute_group {
    > .store = _store, \
    > }
    >
    > +#define __ATTR_DATA(_name,_mode,_show,_store,_data) { \
    > + .attr = {.name = __stringify(_name), .mode = _mode }, \
    > + .show = _show, \
    > + .store = _store, \
    > + .data = (void *)(_data), \
    > +}


    I don't see how this would be any different from the original? You are
    always passed a kobject, which can be embedded in anything else.

    Could you also modify the documentation and the sample code to use this
    new field, showing how it is to be used, and testing that it works
    properly at the same time?

    thanks,

    greg k-h
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  10. Re: [PATCH] exporting capability code/name pairs (try #6)

    Greg KH wrote:
    > On Wed, Feb 20, 2008 at 01:38:59PM +0900, Kohei KaiGai wrote:
    >>>> If we can have a private member in kobj_attribute, we can found the

    >> content
    >>>> to be returned in a single step.
    >>> Ok, again, just send me a patch that adds this functionality and we will
    >>> be very glad to consider it.

    >> [1/2] Add a private data field within kobj_attribute structure.
    >>
    >> This patch add a private data field, declared as void *, within
    >> kobj_attribute
    >> structure. Anyone wants to use sysfs can store their private data to refer
    >> at
    >> _show() and _store() method.
    >> It enables to share a single method function with several similar entries,
    >> like ones to export the list of capabilities the running kernel supported.

    >
    > But your patch 2/2 doesn't use this interface, why not?


    Really?
    The following two _show() methods shared by every capabilities refer
    the private member of kobj_attribute.

    | +static ssize_t capability_name_show(struct kobject *kobj,
    | + struct kobj_attribute *attr,
    | + char *buffer)
    | +{
    | + /* It returns numerical representation of capability. */
    | + return scnprintf(buffer, PAGE_SIZE, "%d\n", (int) attr->data);
    | +}
    | +
    | +static ssize_t capability_code_show(struct kobject *kobj,
    | + struct kobj_attribute *attr,
    | + char *buffer)
    | +{
    | + /* It returns symbolic representation of capability. */
    | + return scnprintf(buffer, PAGE_SIZE, "%s\n", (char *) attr->data);
    | +}

    >> include/linux/kobject.h | 1 +
    >> include/linux/sysfs.h | 7 +++++++
    >> 2 files changed, 8 insertions(+), 0 deletions(-)
    >>
    >> diff --git a/include/linux/kobject.h b/include/linux/kobject.h
    >> index caa3f41..57d5bf1 100644
    >> --- a/include/linux/kobject.h
    >> +++ b/include/linux/kobject.h
    >> @@ -130,6 +130,7 @@ struct kobj_attribute {
    >> char *buf);
    >> ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
    >> const char *buf, size_t count);
    >> + void *data; /* a private field */

    >
    > Hm, can you really use this?


    Yes,

    >> extern struct sysfs_ops kobj_sysfs_ops;
    >> diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
    >> index 8027104..6f40ff9 100644
    >> --- a/include/linux/sysfs.h
    >> +++ b/include/linux/sysfs.h
    >> @@ -50,6 +50,13 @@ struct attribute_group {
    >> .store = _store, \
    >> }
    >>
    >> +#define __ATTR_DATA(_name,_mode,_show,_store,_data) { \
    >> + .attr = {.name = __stringify(_name), .mode = _mode }, \
    >> + .show = _show, \
    >> + .store = _store, \
    >> + .data = (void *)(_data), \
    >> +}

    >
    > I don't see how this would be any different from the original? You are
    > always passed a kobject, which can be embedded in anything else.


    The intension of the latest patch is same as the version which uses
    capability_attribute structure.
    It enables to store the content to be returned in the expanded field.
    Applying kobj_attribute killed needs to declare my own structure.

    However, every entries had its own _show() method, generated by macros
    automatically, in the previous version. It fundamentally differ from
    the latest one.

    > Could you also modify the documentation and the sample code to use this
    > new field, showing how it is to be used, and testing that it works
    > properly at the same time?


    OK, Please wait for a while.

    Thanks,
    --
    OSS Platform Development Division, NEC
    KaiGai Kohei
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  11. Re: [PATCH] exporting capability code/name pairs (try #6)

    On Wed, Feb 20, 2008 at 02:38:16PM +0900, Kohei KaiGai wrote:
    > Greg KH wrote:
    >> On Wed, Feb 20, 2008 at 01:38:59PM +0900, Kohei KaiGai wrote:
    >>>>> If we can have a private member in kobj_attribute, we can found the
    >>> content
    >>>>> to be returned in a single step.
    >>>> Ok, again, just send me a patch that adds this functionality and we will
    >>>> be very glad to consider it.
    >>> [1/2] Add a private data field within kobj_attribute structure.
    >>>
    >>> This patch add a private data field, declared as void *, within
    >>> kobj_attribute
    >>> structure. Anyone wants to use sysfs can store their private data to
    >>> refer at
    >>> _show() and _store() method.
    >>> It enables to share a single method function with several similar
    >>> entries,
    >>> like ones to export the list of capabilities the running kernel
    >>> supported.

    >> But your patch 2/2 doesn't use this interface, why not?

    >
    > Really?
    > The following two _show() methods shared by every capabilities refer
    > the private member of kobj_attribute.
    >
    > | +static ssize_t capability_name_show(struct kobject *kobj,
    > | + struct kobj_attribute *attr,
    > | + char *buffer)
    > | +{
    > | + /* It returns numerical representation of capability. */
    > | + return scnprintf(buffer, PAGE_SIZE, "%d\n", (int) attr->data);
    > | +}
    > | +
    > | +static ssize_t capability_code_show(struct kobject *kobj,
    > | + struct kobj_attribute *attr,
    > | + char *buffer)
    > | +{
    > | + /* It returns symbolic representation of capability. */
    > | + return scnprintf(buffer, PAGE_SIZE, "%s\n", (char *) attr->data);
    > | +}


    Ah, sorry, missed that. I also missed where this was set up as well

    thanks,

    greg k-h
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  12. Re: [PATCH] exporting capability code/name pairs (try #6.1)

    >> Could you also modify the documentation and the sample code to use this
    >> new field, showing how it is to be used, and testing that it works
    >> properly at the same time?

    >
    > OK, Please wait for a while.


    [3/3] Add a new example of kobject/attribute

    The attached patch can provide a new exmple to use kobject and attribute.
    The _show() and _store() method can refer/store the private data field of
    kobj_attribute structure to know what entries are refered by users.
    It will make easier to share a single _show()/_store() method with several
    entries.

    Signed-off-by: KaiGai Kohei
    --
    samples/kobject/kobject-example.c | 32 ++++++++++++++++++++++++++++++++
    1 files changed, 32 insertions(+), 0 deletions(-)

    diff --git a/samples/kobject/kobject-example.c b/samples/kobject/kobject-example.c
    index 08d0d3f..f99d734 100644
    --- a/samples/kobject/kobject-example.c
    +++ b/samples/kobject/kobject-example.c
    @@ -77,6 +77,35 @@ static struct kobj_attribute baz_attribute =
    static struct kobj_attribute bar_attribute =
    __ATTR(bar, 0666, b_show, b_store);

    +/*
    + * You can store a private data within 'data' field of kobj_attribute.
    + * It enables to share a single _show() or _store() method with several
    + * entries.
    + */
    +static ssize_t integer_show(struct kobject *kobj,
    + struct kobj_attribute *attr,
    + char *buf)
    +{
    + return scnprintf(buf, PAGE_SIZE, "%d\n", (int) attr->data);
    +}
    +
    +static ssize_t integer_store(struct kobject *kobj,
    + struct kobj_attribute *attr,
    + const char *buf, size_t count)
    +{
    + int code;
    +
    + sscanf(buf, "%du", &code);
    + attr->data = (void *) code;
    + return count;
    +}
    +
    +static struct kobj_attribute hoge_attribute =
    + __ATTR_DATA(hoge, 0666, integer_show, integer_store, 123);
    +static struct kobj_attribute piyo_attribute =
    + __ATTR_DATA(piyo, 0666, integer_show, integer_store, 456);
    +static struct kobj_attribute fuga_attribute =
    + __ATTR_DATA(fuga, 0444, integer_show, NULL, 789);

    /*
    * Create a group of attributes so that we can create and destory them all
    @@ -86,6 +115,9 @@ static struct attribute *attrs[] = {
    &foo_attribute.attr,
    &baz_attribute.attr,
    &bar_attribute.attr,
    + &hoge_attribute.attr,
    + &piyo_attribute.attr,
    + &fuga_attribute.attr,
    NULL, /* need to NULL terminate the list of attributes */
    };

    --
    OSS Platform Development Division, NEC
    KaiGai Kohei
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  13. Re: [PATCH] exporting capability code/name pairs (try #6.1)

    [Sorry, I sent a patch with TABs translated into spaces.]

    In the attached patch, every attribute entry stores its capability
    identifier in numerical or symbolic representation within private
    data field of kobj_attribute structure.
    The rest of them are unchanged.

    ----
    [2/3] Exporting capability code/name pairs

    This patch enables to export code/name of capabilities supported
    on the running kernel.

    A newer kernel sometimes adds new capabilities, like CAP_MAC_ADMIN
    at 2.6.25. However, we have no interface to disclose what capabilities
    are supported on this kernel. Thus, we have to maintain libcap version
    in appropriate one synchronously.

    This patch enables libcap to collect the list of capabilities on
    run time, and provide them for users.
    It helps to improve portability of library.

    It exports these information as regular files under /sys/kernel/capability.
    The numeric node exports its name, the symbolic node exports its code.

    Please consider to put this patch on the queue of 2.6.25.

    Thanks,
    ================================================== =
    [kaigai@saba ~]$ ls -R /sys/kernel/capability/
    /sys/kernel/capability/:
    codes names version

    /sys/kernel/capability/codes:
    0 10 12 14 16 18 2 21 23 25 27 29 30 32 4 6 8
    1 11 13 15 17 19 20 22 24 26 28 3 31 33 5 7 9

    /sys/kernel/capability/names:
    cap_audit_control cap_kill cap_net_raw cap_sys_nice
    cap_audit_write cap_lease cap_setfcap cap_sys_pacct
    cap_chown cap_linux_immutable cap_setgid cap_sys_ptrace
    cap_dac_override cap_mac_admin cap_setpcap cap_sys_rawio
    cap_dac_read_search cap_mac_override cap_setuid cap_sys_resource
    cap_fowner cap_mknod cap_sys_admin cap_sys_time
    cap_fsetid cap_net_admin cap_sys_boot cap_sys_tty_config
    cap_ipc_lock cap_net_bind_service cap_sys_chroot
    cap_ipc_owner cap_net_broadcast cap_sys_module
    [kaigai@saba ~]$ cat /sys/kernel/capability/version
    0x20071026
    [kaigai@saba ~]$ cat /sys/kernel/capability/codes/30
    cap_audit_control
    [kaigai@saba ~]$ cat /sys/kernel/capability/names/cap_sys_pacct
    20
    [kaigai@saba ~]$
    ================================================== =

    Signed-off-by: KaiGai Kohei
    --
    Documentation/ABI/testing/sysfs-kernel-capability | 23 +++++
    scripts/mkcapnames.sh | 44 +++++++++
    security/Makefile | 9 ++
    security/commoncap.c | 99 +++++++++++++++++++++
    4 files changed, 175 insertions(+), 0 deletions(-)

    diff --git a/Documentation/ABI/testing/sysfs-kernel-capability b/Documentation/ABI/testing/sysfs-kernel-capability
    index e69de29..402ef06 100644
    --- a/Documentation/ABI/testing/sysfs-kernel-capability
    +++ b/Documentation/ABI/testing/sysfs-kernel-capability
    @@ -0,0 +1,23 @@
    +What: /sys/kernel/capability
    +Date: Feb 2008
    +Contact: KaiGai Kohei
    +Description:
    + The entries under /sys/kernel/capability are used to export
    + the list of capabilities the running kernel supported.
    +
    + - /sys/kernel/capability/version
    + returns the most preferable version number for the
    + running kernel.
    + e.g) $ cat /sys/kernel/capability/version
    + 0x20071026
    +
    + - /sys/kernel/capability/code/
    + returns its symbolic representation, on reading.
    + e.g) $ cat /sys/kernel/capability/codes/30
    + cap_audit_control
    +
    + - /sys/kernel/capability/name/
    + returns its numerical representation, on reading.
    + e.g) $ cat /sys/kernel/capability/names/cap_sys_pacct
    + 20
    +
    diff --git a/scripts/mkcapnames.sh b/scripts/mkcapnames.sh
    index e69de29..5d36d52 100644
    --- a/scripts/mkcapnames.sh
    +++ b/scripts/mkcapnames.sh
    @@ -0,0 +1,44 @@
    +#!/bin/sh
    +
    +#
    +# generate a cap_names.h file from include/linux/capability.h
    +#
    +
    +CAPHEAD="`dirname $0`/../include/linux/capability.h"
    +REGEXP='^#define CAP_[A-Z_]+[ ]+[0-9]+$'
    +NUMCAP=`cat "$CAPHEAD" | egrep -c "$REGEXP"`
    +
    +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 '#if !defined(SYSFS_CAP_NAME_ENTRY) || !defined(SYSFS_CAP_CODE_ENTRY)'
    +echo '#error cap_names.h should be included from security/capability.c'
    +echo '#else'
    +echo "#if $NUMCAP != CAP_LAST_CAP + 1"
    +echo '#error mkcapnames.sh cannot collect capabilities correctly'
    +echo '#else'
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("SYSFS_CAP_NAME_ENTRY(%s,%s);\n", tolower($2), $2); }'
    +echo
    +echo 'static struct attribute *capability_name_attrs[] = {'
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("\t&%s_name_attr.attr,\n", tolower($2)); } END { print "\tNULL," }'
    +echo '};'
    +
    +echo
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("SYSFS_CAP_CODE_ENTRY(%s,%s);\n", tolower($2), $2); }'
    +echo
    +echo 'static struct attribute *capability_code_attrs[] = {'
    +cat "$CAPHEAD" | egrep "$REGEXP" \
    + | awk '{ printf("\t&%s_code_attr.attr,\n", tolower($2)); } END { print "\tNULL," }'
    +echo '};'
    +
    +echo '#endif'
    +echo '#endif'
    +echo '#endif'
    diff --git a/security/Makefile b/security/Makefile
    index 9e8b025..c1ffc00 100644
    --- a/security/Makefile
    +++ b/security/Makefile
    @@ -18,3 +18,12 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
    obj-$(CONFIG_SECURITY_SMACK) += commoncap.o smack/built-in.o
    obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o
    obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
    +
    +# cap_names.h contains the code/name pair of capabilities.
    +# It is generated using include/linux/capability.h automatically.
    +$(obj)/commoncap.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)
    diff --git a/security/commoncap.c b/security/commoncap.c
    index 5aba826..2f3b49a 100644
    --- a/security/commoncap.c
    +++ b/security/commoncap.c
    @@ -24,6 +24,8 @@
    #include
    #include
    #include
    +#include
    +#include

    /* Global security state */

    @@ -637,3 +639,100 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
    return __vm_enough_memory(mm, pages, cap_sys_admin);
    }

    +/*
    + * Export the list of capabilities on /sys/kernel/capability
    + */
    +static struct kobject *capability_kobj;
    +
    +static ssize_t capability_name_show(struct kobject *kobj,
    + struct kobj_attribute *attr,
    + char *buffer)
    +{
    + /* It returns numerical representation of capability. */
    + return scnprintf(buffer, PAGE_SIZE, "%d\n", (int) attr->data);
    +}
    +
    +static ssize_t capability_code_show(struct kobject *kobj,
    + struct kobj_attribute *attr,
    + char *buffer)
    +{
    + /* It returns symbolic representation of capability. */
    + return scnprintf(buffer, PAGE_SIZE, "%s\n", (char *) attr->data);
    +}
    +
    +static ssize_t capability_version_show(struct kobject *kobj,
    + struct kobj_attribute *attr,
    + char *buffer)
    +{
    + return scnprintf(buffer, PAGE_SIZE, "0x%08x\n",
    + _LINUX_CAPABILITY_VERSION);
    +}
    +
    +#define SYSFS_CAP_NAME_ENTRY(_name,_code) \
    + static struct kobj_attribute _name##_name_attr = \
    + __ATTR_DATA(_name, 0444, capability_name_show, NULL, (int)(_code))
    +
    +#define SYSFS_CAP_CODE_ENTRY(_name,_code) \
    + static struct kobj_attribute _name##_code_attr = \
    + __ATTR_DATA(_code, 0444, capability_code_show, NULL, __stringify(_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_name_attr_group = {
    + .name = "names",
    + .attrs = capability_name_attrs,
    +};
    +
    +static struct attribute_group capability_code_attr_group = {
    + .name = "codes",
    + .attrs = capability_code_attrs,
    +};
    +
    +static struct kobj_attribute cap_version_attr =
    + __ATTR(version, 0444, capability_version_show, NULL);
    +
    +static int __init capability_export_names(void)
    +{
    + int rc = -ENOMEM;
    +
    + /* make /sys/kernel/capability */
    + capability_kobj = kobject_create_and_add("capability", kernel_kobj);
    + if (!capability_kobj)
    + goto error0;
    +
    + /* make /sys/kernel/capability/names */
    + rc = sysfs_create_group(capability_kobj,
    + &capability_name_attr_group);
    + if (rc)
    + goto error1;
    +
    + /* make /sys/kernel/capability/codes */
    + rc = sysfs_create_group(capability_kobj,
    + &capability_code_attr_group);
    + if (rc)
    + goto error2;
    +
    + /* make /sys/kernel/capability/version */
    + rc = sysfs_create_file(capability_kobj,
    + &cap_version_attr.attr);
    + if (rc)
    + goto error3;
    +
    + return 0;
    +
    +error3:
    + sysfs_remove_group(capability_kobj, &capability_code_attr_group);
    +error2:
    + sysfs_remove_group(capability_kobj, &capability_name_attr_group);
    +error1:
    + kobject_put(capability_kobj);
    +error0:
    + printk(KERN_ERR "Unable to export capabilities\n");
    +
    + return rc;
    +}
    +__initcall(capability_export_names);

    --
    OSS Platform Development Division, NEC
    KaiGai Kohei
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  14. Re: [PATCH] exporting capability code/name pairs (try #6.1)

    [Sorry, I sent a patch with TABs translated into spaces.]

    [1/3] Add a private data field within kobj_attribute structure.

    This patch add a private data field, declared as void *, within kobj_attribute
    structure. Anyone wants to use sysfs can store their private data to refer at
    _show() and _store() method.
    It enables to share a single method function with several similar entries,
    like ones to export the list of capabilities the running kernel supported.

    Signed-off-by: KaiGai Kohei
    --
    include/linux/kobject.h | 1 +
    include/linux/sysfs.h | 7 +++++++
    2 files changed, 8 insertions(+), 0 deletions(-)

    diff --git a/include/linux/kobject.h b/include/linux/kobject.h
    index caa3f41..57d5bf1 100644
    --- a/include/linux/kobject.h
    +++ b/include/linux/kobject.h
    @@ -130,6 +130,7 @@ struct kobj_attribute {
    char *buf);
    ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr,
    const char *buf, size_t count);
    + void *data; /* a private field */
    };

    extern struct sysfs_ops kobj_sysfs_ops;
    diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
    index 8027104..6f40ff9 100644
    --- a/include/linux/sysfs.h
    +++ b/include/linux/sysfs.h
    @@ -50,6 +50,13 @@ struct attribute_group {
    .store = _store, \
    }

    +#define __ATTR_DATA(_name,_mode,_show,_store,_data) { \
    + .attr = {.name = __stringify(_name), .mode = _mode }, \
    + .show = _show, \
    + .store = _store, \
    + .data = (void *)(_data), \
    +}
    +
    #define __ATTR_RO(_name) { \
    .attr = { .name = __stringify(_name), .mode = 0444 }, \
    .show = _name##_show, \

    --
    OSS Platform Development Division, NEC
    KaiGai Kohei
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread
Page 2 of 2 FirstFirst 1 2