lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 27 Dec 2007 10:14:35 -0600
From:	"Serge E. Hallyn" <serue@...ibm.com>
To:	KaiGai Kohei <kaigai@...jp.nec.com>
Cc:	akpm@...l.org, morgan@...nel.org, serue@...ibm.com,
	linux-security-module@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH] Exporting capability code/name pairs

Quoting KaiGai Kohei (kaigai@...jp.nec.com):
> 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.

I like the idea, but

> 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
> #
> 
> -- 
> OSS Platform Development Division, NEC
> KaiGai Kohei <kaigai@...jp.nec.com>
> 
> Signed-off-by: KaiGai Kohei <kaigai@...jp.nec.com>
> ---
>  capability.c |  127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 127 insertions(+)
> 
> diff --git a/kernel/capability.c b/kernel/capability.c
> index efbd9cd..5d9bf53 100644
> --- a/kernel/capability.c
> +++ b/kernel/capability.c
> @@ -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},
> +};

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?

> +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);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists