[lxc-devel] [patch 1/5] Add capability interface

Daniel Lezcano daniel.lezcano at free.fr
Wed Jan 6 22:18:22 UTC 2010


Andrian Nord wrote:
> This adds capabilities.c and capabilities.h files.
>
> Interface consists of three functions:
>
> * initialising function - lxc_capabilities_init:
> 	this function runs though hardoded capability name-to-index
> 	mapping array, checking 'initial_state' field, and builds
> 	initial mask according to this array.
>
> 	Having defaults is a most untrivial question - current default
> 	let container to boot normally and operate properly enough in
> 	most of cases, but restricts all dangerous operations like
> 	module inserting and time changing. But probably this should be
> 	left on system admin's decision (it will also reduce startup
> 	overhead)
>
> * modification functions - lxc_capabilities_change:
> 	this function rather simple. Usage of bit-mask field instead of
> 	say lxc_list is because lxc_list will consume more memory, while
> 	there is not way of removing static array and looking up through
> 	it - we still need mapping from name to mask, so it will also
> 	slower due to additional overhead on comparsions in list (even
> 	if only dropped values whould be kept).
>
> * apply function - lxc_capabilities_apply:
>   

a futile change, but the lxc_capabilities_setup funciton name will be 
more consistent in the context of the other functions in lxc_setup function.
> 	this is most problematic function - as I've failed to found a
> 	way of using libcap (I dunno why it's not working, I'll have
> 	more time to investigate some time later) or raw syscalls, here
> 	I'm checking if capability is dropped and then dropping it with
> 	prctl. Usage of direct mask setting would be, of course,
> 	preffered
>
> Signed-off-by: Andrian Nord <NightNord at gmail.com>
>
> diff --git a/src/lxc/capability.c b/src/lxc/capability.c
> new file mode 100644
> index 0000000..b5fa924
> --- /dev/null
> +++ b/src/lxc/capability.c
> @@ -0,0 +1,167 @@
> +/*
> + * lxc: linux Container library
> + *
> + * (C) Copyright IBM Corp. 2007, 2008
> + *
> + * Authors:
> + * Daniel Lezcano <dlezcano at fr.ibm.com>
> + * File by:
> + * Andrian Nord <nightnord at gmail.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + */
> +
> +#undef _GNU_SOURCE
> +#include <errno.h>
> +#include <linux/types.h>
> +#include <sys/prctl.h>
> +#include <sys/capability.h>
> +
> +#include "capability.h"
> +
> +#include <lxc/log.h>
> +
> +#if !HAVE_DECL_PR_CAPBSET_DROP
> +#define PR_CAPBSET_DROP 24
> +#endif
> +
> +lxc_log_define(lxc_capability, lxc);
> +
> +struct capability {
> +	char		*name;
> +	__u32		code;
> +	lxc_cap_state	initial_state;
> +};
>   
I think you can define the structure as follow,

struct capability {
	char		*name;
	__u32		code;
	int             drop;
};

And then initialize:

static struct capability capabilities[] = {
	{ "chown",		CAP_CHOWN },
	...
	{ "sys_module",          CAP_SYS_MODULE, 1 },
	...
};


> +static const size_t cap_count = sizeof(capabilities)/sizeof(struct capability);
> +
> +static struct capability *find_name(const char *cap_name)
> +{
> +	int i;
> +
> +	for (i = 0; i < cap_count; i++) {
> +		if (!strncmp(capabilities[i].name, cap_name, strlen(cap_name)))
> +			return &capabilities[i];
> +	}
> +
> +	return NULL;
> +}
> +
> +int lxc_capabilities_init(__u32 *mask)
> +{
> +	int i;
> +	*mask = 0;
> +
> +	for (i = 0; i < cap_count; i++) {
> +		if(capabilities[i].initial_state == LXC_CAP_KEEP)
> +			*mask |= CAP_TO_MASK(capabilities[i].code);
> +	}
> +
> +	return 0;
> +}
> +
> +int lxc_capabilities_change(__u32 *mask, const char *cap_name,
> +							lxc_cap_state state)
> +{
> +	struct capability *cap_spec;
> +
> +	cap_spec = find_name(cap_name);
> +
> +	if (!cap_spec) {
> +		ERROR("capability '%s' not found", cap_name);
> +		return -1;
> +	}
> +
> +	if (state == LXC_CAP_DROP)
> +		*mask &= ~CAP_TO_MASK(cap_spec->code);
> +	else if (state == LXC_CAP_KEEP)
> +		*mask |= CAP_TO_MASK(cap_spec->code);
> +
> +	return 0;
> +}
> +
> +
> +int lxc_capabilities_apply(__u32 mask)
> +{
> +	int i;
> +	struct capability *cur_cap;
> +
> +	for (i = 0; i < cap_count; i++) {
> +		cur_cap = &capabilities[i];
> +
> +		if (lxc_capabilities_check(mask, cur_cap->code))
> +			continue;
> +
> +		DEBUG("dropping capability '%s'", cur_cap->name);
> +
> +	 	if (!prctl(PR_CAPBSET_DROP, cur_cap->code, 0, 0, 0))
> +			continue;
> +
> +		SYSERROR("failed to remove '%s' capability", cur_cap->name);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> diff --git a/src/lxc/capability.h b/src/lxc/capability.h
> new file mode 100644
> index 0000000..401ad2a
> --- /dev/null
> +++ b/src/lxc/capability.h
> @@ -0,0 +1,44 @@
> +/*
> + * lxc: linux Container library
> + *
> + * (C) Copyright IBM Corp. 2007, 2008
> + *
> + * Authors:
> + * Daniel Lezcano <dlezcano at fr.ibm.com>
> + * File by:
> + * Andrian Nord <nightnord at gmail.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + */
> +#ifndef _capability_h
> +#define _capability_h
> +
> +#include <linux/types.h>
> +
> +#define lxc_capabilities_check(mask, code) (mask & CAP_TO_MASK(code))
>   
This macro can be moved to capability.c, no ?

> +
> +typedef enum {
> +	LXC_CAP_DROP	= 0,
> +	LXC_CAP_KEEP	= 1
> +} lxc_cap_state;
> +
> +int lxc_capabilities_init(__u32 *mask);
> +
> +int lxc_capabilities_change(__u32 *mask, const char *cap_name,
> +							lxc_cap_state state);
> +
> +int lxc_capabilities_apply(__u32 mask);
> +
> +#endif
>
>   
Otherwise, the patchset looks good, including the default values for the 
dropped capabilities.

Thanks
  -- Daniel




More information about the lxc-devel mailing list