[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