Add support for the unshare mask
authorAsbjorn Sannes <asbjorn.sannes@interhost.no>
Tue, 31 May 2011 09:55:54 +0000 (11:55 +0200)
committerDaniel Hokka Zakrisson <daniel@hozac.com>
Tue, 31 May 2011 12:19:19 +0000 (14:19 +0200)
13 files changed:
doc/configuration.xml
ensc_wrappers/wrappers-vserver.hc
kernel/context_cmd.h
lib/Makefile-files
lib/syscall_getumask-v23.hc [new file with mode: 0644]
lib/syscall_getumask.c [new file with mode: 0644]
lib/syscall_setumask-v23.hc [new file with mode: 0644]
lib/syscall_setumask.c [new file with mode: 0644]
lib/umask-v23.c [new file with mode: 0644]
lib/umask_list-v23.c [new file with mode: 0644]
lib/vserver.h
scripts/vserver.functions
src/vattribute.c

index 3e48568..fc7416f 100644 (file)
@@ -512,6 +512,13 @@ url="http://svn.linux-vserver.org/svn/util-vserver/trunk/lib/ncaps-net.c">lib/nc
 for possible values.
       </description>
     </list>
+    <list name="umask" since="0.30.216">
+      <description>
+Contains the namespaces allowed to be unshared. See <ulink
+url="http://svn.linux-vserver.org/svn/util-vserver/trunk/lib/umask-v23.c">lib/umask-v23.c</ulink>
+for possible values.
+      </description>
+    </list>
 
     <boolean id="global-namespace" name="namespace">
       <description>
index c134c35..f3e1f47 100644 (file)
@@ -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()");
index 7b4f2ae..9c50f71 100644 (file)
@@ -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)
index e607f53..1db4a53 100644 (file)
@@ -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 (file)
index 0000000..1c2042f
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright (C) 2011 Asbjorn Sannes <asbjorn.sannes@interhost.no>
+//  
+// 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 <config.h>
+#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 (file)
index 0000000..8c6ef37
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (C) 2011 Asbjorn Sannes <asbjorn.sannes@interhost.no>
+//  
+// 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 <config.h>
+#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 (file)
index 0000000..eec326e
--- /dev/null
@@ -0,0 +1,30 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2011 Asbjorn Sannes <asbjorn.sannes@interhost.no>
+//  
+// 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 <config.h>
+#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 (file)
index 0000000..6e5fab2
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright (C) 2011 Asbjorn Sannes <asbjorn.sannes@interhost.no>
+//  
+// 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 <config.h>
+#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 (file)
index 0000000..fdefad4
--- /dev/null
@@ -0,0 +1,58 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2011 Asbjorn Sannes <asbjorn.sannes@interhost.no>
+//  
+// 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 <config.h>
+#endif
+
+#include "vserver.h"
+#include "internal.h"
+#include <lib_internal/util-dimof.h>
+
+#include <string.h>
+#include <strings.h>
+#include <assert.h>
+
+#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 (file)
index 0000000..2afd690
--- /dev/null
@@ -0,0 +1,46 @@
+// $Id$    --*- c -*--
+
+// Copyright (C) 2011 Asbjorn Sannes <asbjorn.sannes@interhost.no>
+//  
+// 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 <config.h>
+#endif
+
+#include "vserver.h"
+#include "internal.h"
+
+#include <string.h>
+
+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);
+}
index 1d553f4..b2858fa 100644 (file)
@@ -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);
index a10344d..d10ccf2 100644 (file)
@@ -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[@]}" \
index 86e90ba..ef4d665 100644 (file)
@@ -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 <cap>   ...  system  capability to be set\n"
            " --ccap <cap>   ...  context capability to be set\n"
            " --flag <flag>  ...  context flag to be set\n"
+           " --umask <mask> ...  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<argc)
       EexecvpD(argv[optind], argv+optind);
     else