From 989f6cc00a65b6c06f1453f50abc442a28dad714 Mon Sep 17 00:00:00 2001 From: Asbjorn Sannes Date: Tue, 31 May 2011 11:55:54 +0200 Subject: [PATCH] Add support for the unshare mask --- doc/configuration.xml | 7 +++++ ensc_wrappers/wrappers-vserver.hc | 6 ++++ kernel/context_cmd.h | 12 ++++++++ lib/Makefile-files | 8 +++++- lib/syscall_getumask-v23.hc | 29 ++++++++++++++++++++ lib/syscall_getumask.c | 38 +++++++++++++++++++++++++ lib/syscall_setumask-v23.hc | 30 ++++++++++++++++++++ lib/syscall_setumask.c | 39 ++++++++++++++++++++++++++ lib/umask-v23.c | 58 +++++++++++++++++++++++++++++++++++++++ lib/umask_list-v23.c | 46 +++++++++++++++++++++++++++++++ lib/vserver.h | 14 +++++++++- scripts/vserver.functions | 8 ++++++ src/vattribute.c | 28 +++++++++++++++++++ 13 files changed, 321 insertions(+), 2 deletions(-) create mode 100644 lib/syscall_getumask-v23.hc create mode 100644 lib/syscall_getumask.c create mode 100644 lib/syscall_setumask-v23.hc create mode 100644 lib/syscall_setumask.c create mode 100644 lib/umask-v23.c create mode 100644 lib/umask_list-v23.c diff --git a/doc/configuration.xml b/doc/configuration.xml index 3e48568..fc7416f 100644 --- a/doc/configuration.xml +++ b/doc/configuration.xml @@ -512,6 +512,13 @@ url="http://svn.linux-vserver.org/svn/util-vserver/trunk/lib/ncaps-net.c">lib/nc for possible values. + + +Contains the namespaces allowed to be unshared. See lib/umask-v23.c +for possible values. + + diff --git a/ensc_wrappers/wrappers-vserver.hc b/ensc_wrappers/wrappers-vserver.hc index c134c35..f3e1f47 100644 --- a/ensc_wrappers/wrappers-vserver.hc +++ b/ensc_wrappers/wrappers-vserver.hc @@ -134,6 +134,12 @@ Evc_set_ccaps(xid_t xid, struct vc_ctx_caps const *caps) } inline static WRAPPER_DECL void +Evc_get_umask(xid_t xid, struct vc_umask *umask) +{ + FatalErrnoError(vc_get_umask(xid, umask)==-1, "vc_get_umask()"); +} + +inline static WRAPPER_DECL void Evc_get_ncaps(nid_t nid, struct vc_net_caps *caps) { FatalErrnoError(vc_get_ncaps(nid, caps)==-1, "vc_get_ncaps()"); diff --git a/kernel/context_cmd.h b/kernel/context_cmd.h index 7b4f2ae..9c50f71 100644 --- a/kernel/context_cmd.h +++ b/kernel/context_cmd.h @@ -90,6 +90,18 @@ struct vcmd_bcaps { +/* umask commands */ + +#define VCMD_get_umask VC_CMD(FLAGS, 13, 0) +#define VCMD_set_umask VC_CMD(FLAGS, 14, 0) + +struct vcmd_umask { + uint64_t umask; + uint64_t mask; +}; + + + /* OOM badness */ #define VCMD_get_badness VC_CMD(MEMCTRL, 5, 0) diff --git a/lib/Makefile-files b/lib/Makefile-files index e607f53..1db4a53 100644 --- a/lib/Makefile-files +++ b/lib/Makefile-files @@ -157,12 +157,18 @@ lib_v23_SRCS = lib/syscall_tagmigrate-v23.hc \ lib/syscall_getbadness.c \ lib/syscall_getbadness-v23.hc \ lib/syscall_setbadness.c \ + lib/syscall_setumask-v23.hc \ + lib/syscall_setumask.c \ + lib/syscall_getumask-v23.hc \ + lib/syscall_getumask.c \ lib/syscall_setbadness-v23.hc \ lib/syscall_getspacedefault.c \ lib/syscall_getspacedefault-v23.hc \ lib/syscall_setnamespace-v23.hc \ lib/syscall_enternamespace-v23.hc \ - lib/syscall_getspacemask-v23.hc + lib/syscall_getspacemask-v23.hc \ + lib/umask-v23.c \ + lib/umask_list-v23.c if ENSC_HAVE_C99_COMPILER lib_v13_SRCS += lib/syscall_adddlimit-v13.hc \ diff --git a/lib/syscall_getumask-v23.hc b/lib/syscall_getumask-v23.hc new file mode 100644 index 0000000..1c2042f --- /dev/null +++ b/lib/syscall_getumask-v23.hc @@ -0,0 +1,29 @@ +// Copyright (C) 2011 Asbjorn Sannes +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifdef HAVE_CONFIG_H +# include +#endif + +static inline ALWAYSINLINE int +vc_get_umask_v23(xid_t xid, struct vc_umask *umask) +{ + int res; + struct vcmd_umask data; + res = vserver(VCMD_get_umask, CTX_USER2KERNEL(xid), &data); + umask->umask = data.umask; + umask->mask = data.mask; + return res; +} diff --git a/lib/syscall_getumask.c b/lib/syscall_getumask.c new file mode 100644 index 0000000..8c6ef37 --- /dev/null +++ b/lib/syscall_getumask.c @@ -0,0 +1,38 @@ +// Copyright (C) 2011 Asbjorn Sannes +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "virtual.h" +#include "vserver-internal.h" + +#if defined(VC_ENABLE_API_V23) +# include "syscall_getumask-v23.hc" +#endif + +#if defined(VC_ENABLE_API_V23) +int +vc_get_umask(xid_t xid, struct vc_umask *umask) +{ + if (umask==NULL) { + errno = EFAULT; + return -1; + } + CALL_VC(CALL_VC_V23(vc_get_umask, xid, umask)); +} +#endif diff --git a/lib/syscall_setumask-v23.hc b/lib/syscall_setumask-v23.hc new file mode 100644 index 0000000..eec326e --- /dev/null +++ b/lib/syscall_setumask-v23.hc @@ -0,0 +1,30 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2011 Asbjorn Sannes +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifdef HAVE_CONFIG_H +# include +#endif + +static inline ALWAYSINLINE int +vc_set_umask_v23(xid_t xid, struct vc_umask const *umask) +{ + struct vcmd_umask data = { + .umask = umask->umask, + .mask = umask->mask, + }; + return vserver(VCMD_set_umask, CTX_USER2KERNEL(xid), &data); +} diff --git a/lib/syscall_setumask.c b/lib/syscall_setumask.c new file mode 100644 index 0000000..6e5fab2 --- /dev/null +++ b/lib/syscall_setumask.c @@ -0,0 +1,39 @@ +// Copyright (C) 2011 Asbjorn Sannes +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "virtual.h" +#include "vserver-internal.h" + +#if defined(VC_ENABLE_API_V23) +# include "syscall_setumask-v23.hc" +#endif + +#if defined(VC_ENABLE_API_V23) +int +vc_set_umask(xid_t xid, struct vc_umask const *umask) +{ + if (umask==NULL) { + errno = EFAULT; + return -1; + } + + CALL_VC(CALL_VC_V23(vc_set_umask, xid, umask)); +} +#endif diff --git a/lib/umask-v23.c b/lib/umask-v23.c new file mode 100644 index 0000000..fdefad4 --- /dev/null +++ b/lib/umask-v23.c @@ -0,0 +1,58 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2011 Asbjorn Sannes +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "internal.h" +#include + +#include +#include +#include + +#define DECL(STR, VAL) { STR, sizeof(STR)-1, VAL } + +static struct Mapping_uint64 const VALUES[] = { + DECL("fs", CLONE_FS), + DECL("newns", CLONE_NEWNS), + DECL("newuts", CLONE_NEWUTS), + DECL("newipc", CLONE_NEWIPC), + DECL("newuser", CLONE_NEWUSER), + DECL("newpid", CLONE_NEWPID), + DECL("newnet", CLONE_NEWNET), +}; + +uint_least64_t +vc_text2umask(char const *str, size_t len) +{ + ssize_t idx = utilvserver_value2text_uint64(str, len, + VALUES, DIM_OF(VALUES)); + if (idx==-1) return 0; + else return VALUES[idx].val; +} + +char const * +vc_loumask2text(uint_least64_t *val) +{ + ssize_t idx = utilvserver_text2value_uint64(val, + VALUES, DIM_OF(VALUES)); + if (idx==-1) return 0; + else return VALUES[idx].id; +} diff --git a/lib/umask_list-v23.c b/lib/umask_list-v23.c new file mode 100644 index 0000000..2afd690 --- /dev/null +++ b/lib/umask_list-v23.c @@ -0,0 +1,46 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2011 Asbjorn Sannes +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "internal.h" + +#include + +static uint_least64_t +vc_text2umask_err(char const *str, size_t len, bool *failed) +{ + uint_least64_t res = vc_text2umask(str, len); + if (res==0) *failed = true; + return res; +} + +int +vc_list2umask(char const *str, size_t len, + struct vc_err_listparser *err, + struct vc_umask *umask) +{ + return utilvserver_listparser_uint64(str, len, + err ? &err->ptr : 0, + err ? &err->len : 0, + &umask->umask, &umask->mask, + vc_text2umask_err); +} diff --git a/lib/vserver.h b/lib/vserver.h index 1d553f4..b2858fa 100644 --- a/lib/vserver.h +++ b/lib/vserver.h @@ -862,6 +862,15 @@ extern "C" { int vc_set_badness(xid_t xid, int64_t badness); + /** \brief Namespaces allowed to unshare */ + struct vc_umask { + uint_least64_t umask; + uint_least64_t mask; + }; + + int vc_get_umask(xid_t xid, struct vc_umask *umask); + int vc_set_umask(xid_t xid, struct vc_umask const *umask); + /** \brief Information about parsing errors * \ingroup helper */ @@ -934,7 +943,10 @@ extern "C" { int vc_list2ccap(char const *, size_t len, struct vc_err_listparser *err, struct vc_ctx_caps *); - + char const * vc_loumask2text(uint_least64_t *); + int vc_list2umask(char const *, size_t len, + struct vc_err_listparser *err, + struct vc_umask *); int vc_list2cflag(char const *, size_t len, struct vc_err_listparser *err, struct vc_ctx_flags *flags); diff --git a/scripts/vserver.functions b/scripts/vserver.functions index a10344d..d10ccf2 100644 --- a/scripts/vserver.functions +++ b/scripts/vserver.functions @@ -206,6 +206,13 @@ function _generateBCapabilityOptions _readFileToArray "$vdir"/bcapabilities OPTS_VATTRIBUTE --bcap } +function _generateUMaskOptions +{ + local vdir=$1 + + _readFileToArray "$vdir"/umask OPTS_VATTRIBUTE --umask +} + function _generateCapabilityOptions { local vdir=$1 @@ -442,6 +449,7 @@ function _generateChcontextOptions _generateCapabilityOptions "$vdir" _generateFlagOptions "$vdir" + _generateUMaskOptions "$vdir" CHCONTEXT_OPTS=( $SILENT_OPT \ "${CHCONTEXT_FLAG_OPTS[@]}" \ diff --git a/src/vattribute.c b/src/vattribute.c index 86e90ba..ef4d665 100644 --- a/src/vattribute.c +++ b/src/vattribute.c @@ -42,6 +42,7 @@ #define CMD_SECURE 0x2004 #define CMD_BCAP 0x2005 #define CMD_GET 0x2006 +#define CMD_UMASK 0x2007 int wrapper_exit_code = 1; @@ -56,6 +57,7 @@ CMDLINE_OPTIONS[] = { { "bcap", required_argument, 0, CMD_BCAP }, { "flag", required_argument, 0, CMD_FLAG }, { "secure", no_argument, 0, CMD_SECURE }, + { "umask", required_argument, 0, CMD_UMASK }, {0,0,0,0} }; @@ -63,6 +65,7 @@ struct Arguments { xid_t xid; struct vc_ctx_flags flags; struct vc_ctx_caps caps; + struct vc_umask umask; int mode; }; @@ -78,6 +81,7 @@ showHelp(int fd, char const *cmd, int res) " --bcap ... system capability to be set\n" " --ccap ... context capability to be set\n" " --flag ... context flag to be set\n" + " --umask ... unshare mask to be set\n" "\n" "Please report bugs to " PACKAGE_BUGREPORT "\n"); @@ -144,6 +148,22 @@ parseCCaps(char const *str, struct vc_ctx_caps *caps) } static void +parseUMask(char const *str, struct vc_umask *umask) +{ + struct vc_err_listparser err; + int rc; + + rc = vc_list2umask(str, 0, &err, umask); + + if (rc==-1) { + WRITE_MSG(2, "Unknown namespace '"); + Vwrite(2, err.ptr, err.len); + WRITE_MSG(2, "'\n"); + exit(wrapper_exit_code); + } +} + +static void parseSecure(struct vc_ctx_flags UNUSED * flags, struct vc_ctx_caps UNUSED * caps) { @@ -162,13 +182,16 @@ printAttrs(struct Arguments *args) { struct vc_ctx_flags flags; struct vc_ctx_caps caps; + struct vc_umask umask = { .mask = ~0, .umask = 0x20200 }; Evc_get_cflags(args->xid, &flags); Evc_get_ccaps(args->xid, &caps); + Evc_get_umask(args->xid, &umask); print_bitfield(1, bcap, "bcapabilities", &caps.bcaps); print_bitfield(1, ccap, "ccapabilities", &caps.ccaps); print_bitfield(1, cflag, "flags", &flags.flagword); + print_bitfield(1, umask, "umask", &umask.umask); return 0; } @@ -179,6 +202,7 @@ int main(int argc, char *argv[]) .xid = VC_NOCTX, .flags = { .flagword = 0, .mask = 0 }, .caps = { .bcaps = 0, .bmask = 0,.ccaps = 0, .cmask = 0 }, + .umask = { .umask = 0, .mask = 0 }, .mode = CMD_SET, }; @@ -196,6 +220,7 @@ int main(int argc, char *argv[]) case CMD_CCAP : parseCCaps(optarg, &args.caps); break; case CMD_BCAP : parseBCaps(optarg, &args.caps); break; case CMD_SECURE : parseSecure(&args.flags, &args.caps); break; + case CMD_UMASK : parseUMask(optarg, &args.umask); break; default : WRITE_MSG(2, "Try '"); WRITE_STR(2, argv[0]); @@ -214,6 +239,9 @@ int main(int argc, char *argv[]) else if (args.flags.mask && vc_set_cflags(args.xid, &args.flags)==-1) perror(ENSC_WRAPPERS_PREFIX "vc_set_flags()"); + else if (args.umask.mask && + vc_set_umask(args.xid, &args.umask)==-1) + perror(ENSC_WRAPPERS_PREFIX "vc_set_umask()"); else if (optind