config: support mounts
authorRobert Swiecki <robert@swiecki.net>
Fri, 26 May 2017 23:16:12 +0000 (01:16 +0200)
committerRobert Swiecki <robert@swiecki.net>
Fri, 26 May 2017 23:16:12 +0000 (01:16 +0200)
Makefile
config.c
config.example
config.pb-c.c
config.pb-c.h
config.proto
util.c
util.h

index 31cc4a583964a16ffb19c56ed1817ed0c54b63f3..71405d46b8e57b7aa54abfd03cf7e106fd826e59 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -103,7 +103,7 @@ indent:
 
 nsjail.o: nsjail.h common.h cmdline.h log.h net.h subproc.h
 cmdline.o: cmdline.h common.h config.h log.h mount.h util.h user.h
-config.o: common.h config.h log.h user.h util.h
+config.o: common.h config.h log.h mount.h user.h util.h
 contain.o: contain.h common.h cgroup.h log.h mount.h net.h pid.h user.h
 contain.o: util.h uts.h
 log.o: log.h common.h
index ba0fb658880ef43799247ec378c39ac764c0359d..2ff1fae2b99238edcc43d3b785524292e0a14f0b 100644 (file)
--- a/config.c
+++ b/config.c
 #include "common.h"
 
 #include <stdio.h>
+#include <sys/mount.h>
 #include <sys/personality.h>
 
 #include "config.h"
 #include "log.h"
+#include "mount.h"
 #include "user.h"
 #include "util.h"
 
@@ -177,6 +179,26 @@ static bool configParseInternal(struct nsjconf_t *nsjconf, Nsjail__NsJailConfig
                }
        }
 
+       for (size_t i = 0; i < njc->n_mount; i++) {
+               struct mounts_t *p = utilCalloc(sizeof(struct mounts_t));
+               p->src = utilStrDup(njc->mount[i]->src);
+               p->dst = utilStrDup(njc->mount[i]->dst);
+               p->fs_type = utilStrDup(njc->mount[i]->fstype);
+               p->options = utilStrDup(njc->mount[i]->options);
+               p->flags |= (njc->mount[i]->is_ro ? MS_RDONLY : 0);
+               p->flags |= (njc->mount[i]->is_bind ? (MS_BIND | MS_REC) : 0);
+               if (njc->mount[i]->has_is_dir) {
+                       p->isDir = njc->mount[i]->is_dir;
+               } else {
+                       if (njc->mount[i]->is_bind) {
+                               p->isDir = mountIsDir(njc->mount[i]->src);
+                       } else {
+                               p->isDir = true;
+                       }
+               }
+               TAILQ_INSERT_HEAD(&nsjconf->mountpts, p, pointers);
+       }
+
        return true;
 }
 
index c23247dca403022c09b2eb492c458d1e7829d74a..1ab09dab70fbc8a9499b249968d2661e9bf844fd 100644 (file)
@@ -50,3 +50,30 @@ gidmap {
        outside_id: ""
        count: 1
 }
+
+mount {
+       src: ""
+       dst: "/tmp"
+       fstype: "tmpfs"
+       options: ""
+       is_ro: false
+       is_bind: false
+}
+
+mount {
+       src: ""
+       dst: "/dev"
+       fstype: "tmpfs"
+       options: ""
+       is_ro: false
+       is_bind: false
+}
+
+mount {
+       src: "/dev/null"
+       dst: "/dev/null"
+       fstype: ""
+       options: ""
+       is_ro: false
+       is_bind: true
+}
index 00c99924462e76e99d34eea158644cf46b5fa357..e45d6a34ee2131545a2018130a21f05bbd72ad8e 100644 (file)
@@ -7,22 +7,26 @@
 #endif
 
 #include "config.pb-c.h"
-void nsjail__id_map__init(Nsjail__IdMap * message) {
+void nsjail__id_map__init(Nsjail__IdMap * message)
+{
        static Nsjail__IdMap init_value = NSJAIL__ID_MAP__INIT;
        *message = init_value;
 }
 
-size_t nsjail__id_map__get_packed_size(const Nsjail__IdMap * message) {
+size_t nsjail__id_map__get_packed_size(const Nsjail__IdMap * message)
+{
        assert(message->base.descriptor == &nsjail__id_map__descriptor);
        return protobuf_c_message_get_packed_size((const ProtobufCMessage *)(message));
 }
 
-size_t nsjail__id_map__pack(const Nsjail__IdMap * message, uint8_t * out) {
+size_t nsjail__id_map__pack(const Nsjail__IdMap * message, uint8_t * out)
+{
        assert(message->base.descriptor == &nsjail__id_map__descriptor);
        return protobuf_c_message_pack((const ProtobufCMessage *)message, out);
 }
 
-size_t nsjail__id_map__pack_to_buffer(const Nsjail__IdMap * message, ProtobufCBuffer * buffer) {
+size_t nsjail__id_map__pack_to_buffer(const Nsjail__IdMap * message, ProtobufCBuffer * buffer)
+{
        assert(message->base.descriptor == &nsjail__id_map__descriptor);
        return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *)message, buffer);
 }
@@ -33,22 +37,62 @@ Nsjail__IdMap *nsjail__id_map__unpack
            protobuf_c_message_unpack(&nsjail__id_map__descriptor, allocator, len, data);
 }
 
-void nsjail__id_map__free_unpacked(Nsjail__IdMap * message, ProtobufCAllocator * allocator) {
+void nsjail__id_map__free_unpacked(Nsjail__IdMap * message, ProtobufCAllocator * allocator)
+{
        assert(message->base.descriptor == &nsjail__id_map__descriptor);
        protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator);
 }
 
-void nsjail__ns_jail_config__init(Nsjail__NsJailConfig * message) {
+void nsjail__mount_pt__init(Nsjail__MountPt * message)
+{
+       static Nsjail__MountPt init_value = NSJAIL__MOUNT_PT__INIT;
+       *message = init_value;
+}
+
+size_t nsjail__mount_pt__get_packed_size(const Nsjail__MountPt * message)
+{
+       assert(message->base.descriptor == &nsjail__mount_pt__descriptor);
+       return protobuf_c_message_get_packed_size((const ProtobufCMessage *)(message));
+}
+
+size_t nsjail__mount_pt__pack(const Nsjail__MountPt * message, uint8_t * out)
+{
+       assert(message->base.descriptor == &nsjail__mount_pt__descriptor);
+       return protobuf_c_message_pack((const ProtobufCMessage *)message, out);
+}
+
+size_t nsjail__mount_pt__pack_to_buffer(const Nsjail__MountPt * message, ProtobufCBuffer * buffer)
+{
+       assert(message->base.descriptor == &nsjail__mount_pt__descriptor);
+       return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *)message, buffer);
+}
+
+Nsjail__MountPt *nsjail__mount_pt__unpack
+    (ProtobufCAllocator * allocator, size_t len, const uint8_t * data) {
+       return (Nsjail__MountPt *)
+           protobuf_c_message_unpack(&nsjail__mount_pt__descriptor, allocator, len, data);
+}
+
+void nsjail__mount_pt__free_unpacked(Nsjail__MountPt * message, ProtobufCAllocator * allocator)
+{
+       assert(message->base.descriptor == &nsjail__mount_pt__descriptor);
+       protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator);
+}
+
+void nsjail__ns_jail_config__init(Nsjail__NsJailConfig * message)
+{
        static Nsjail__NsJailConfig init_value = NSJAIL__NS_JAIL_CONFIG__INIT;
        *message = init_value;
 }
 
-size_t nsjail__ns_jail_config__get_packed_size(const Nsjail__NsJailConfig * message) {
+size_t nsjail__ns_jail_config__get_packed_size(const Nsjail__NsJailConfig * message)
+{
        assert(message->base.descriptor == &nsjail__ns_jail_config__descriptor);
        return protobuf_c_message_get_packed_size((const ProtobufCMessage *)(message));
 }
 
-size_t nsjail__ns_jail_config__pack(const Nsjail__NsJailConfig * message, uint8_t * out) {
+size_t nsjail__ns_jail_config__pack(const Nsjail__NsJailConfig * message, uint8_t * out)
+{
        assert(message->base.descriptor == &nsjail__ns_jail_config__descriptor);
        return protobuf_c_message_pack((const ProtobufCMessage *)message, out);
 }
@@ -153,6 +197,126 @@ const ProtobufCMessageDescriptor nsjail__id_map__descriptor = {
        NULL, NULL, NULL        /* reserved[123] */
 };
 
+char nsjail__mount_pt__options__default_value[] = "";
+static const protobuf_c_boolean nsjail__mount_pt__is_bind__default_value = 0;
+static const protobuf_c_boolean nsjail__mount_pt__is_ro__default_value = 0;
+static const ProtobufCFieldDescriptor nsjail__mount_pt__field_descriptors[7] = {
+       {
+        "src",
+        1,
+        PROTOBUF_C_LABEL_REQUIRED,
+        PROTOBUF_C_TYPE_STRING,
+        0,                     /* quantifier_offset */
+        offsetof(Nsjail__MountPt, src),
+        NULL,
+        NULL,
+        0,                     /* flags */
+        0, NULL, NULL          /* reserved1,reserved2, etc */
+        },
+       {
+        "dst",
+        2,
+        PROTOBUF_C_LABEL_REQUIRED,
+        PROTOBUF_C_TYPE_STRING,
+        0,                     /* quantifier_offset */
+        offsetof(Nsjail__MountPt, dst),
+        NULL,
+        NULL,
+        0,                     /* flags */
+        0, NULL, NULL          /* reserved1,reserved2, etc */
+        },
+       {
+        "fstype",
+        3,
+        PROTOBUF_C_LABEL_REQUIRED,
+        PROTOBUF_C_TYPE_STRING,
+        0,                     /* quantifier_offset */
+        offsetof(Nsjail__MountPt, fstype),
+        NULL,
+        NULL,
+        0,                     /* flags */
+        0, NULL, NULL          /* reserved1,reserved2, etc */
+        },
+       {
+        "options",
+        4,
+        PROTOBUF_C_LABEL_REQUIRED,
+        PROTOBUF_C_TYPE_STRING,
+        0,                     /* quantifier_offset */
+        offsetof(Nsjail__MountPt, options),
+        NULL,
+        &nsjail__mount_pt__options__default_value,
+        0,                     /* flags */
+        0, NULL, NULL          /* reserved1,reserved2, etc */
+        },
+       {
+        "is_bind",
+        5,
+        PROTOBUF_C_LABEL_REQUIRED,
+        PROTOBUF_C_TYPE_BOOL,
+        0,                     /* quantifier_offset */
+        offsetof(Nsjail__MountPt, is_bind),
+        NULL,
+        &nsjail__mount_pt__is_bind__default_value,
+        0,                     /* flags */
+        0, NULL, NULL          /* reserved1,reserved2, etc */
+        },
+       {
+        "is_ro",
+        6,
+        PROTOBUF_C_LABEL_REQUIRED,
+        PROTOBUF_C_TYPE_BOOL,
+        0,                     /* quantifier_offset */
+        offsetof(Nsjail__MountPt, is_ro),
+        NULL,
+        &nsjail__mount_pt__is_ro__default_value,
+        0,                     /* flags */
+        0, NULL, NULL          /* reserved1,reserved2, etc */
+        },
+       {
+        "is_dir",
+        7,
+        PROTOBUF_C_LABEL_OPTIONAL,
+        PROTOBUF_C_TYPE_BOOL,
+        offsetof(Nsjail__MountPt, has_is_dir),
+        offsetof(Nsjail__MountPt, is_dir),
+        NULL,
+        NULL,
+        0,                     /* flags */
+        0, NULL, NULL          /* reserved1,reserved2, etc */
+        },
+};
+
+static const unsigned nsjail__mount_pt__field_indices_by_name[] = {
+       1,                      /* field[1] = dst */
+       2,                      /* field[2] = fstype */
+       4,                      /* field[4] = is_bind */
+       6,                      /* field[6] = is_dir */
+       5,                      /* field[5] = is_ro */
+       3,                      /* field[3] = options */
+       0,                      /* field[0] = src */
+};
+
+static const ProtobufCIntRange nsjail__mount_pt__number_ranges[1 + 1] = {
+       {1, 0},
+       {0, 7}
+};
+
+const ProtobufCMessageDescriptor nsjail__mount_pt__descriptor = {
+       PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
+       "nsjail.MountPt",
+       "MountPt",
+       "Nsjail__MountPt",
+       "nsjail",
+       sizeof(Nsjail__MountPt),
+       7,
+       nsjail__mount_pt__field_descriptors,
+       nsjail__mount_pt__field_indices_by_name,
+       1, nsjail__mount_pt__number_ranges,
+       (ProtobufCMessageInit) nsjail__mount_pt__init,
+       NULL, NULL, NULL        /* reserved[123] */
+};
+
 char nsjail__ns_jail_config__hostname__default_value[] = "NSJAIL";
 char nsjail__ns_jail_config__cwd__default_value[] = "/";
 char nsjail__ns_jail_config__bindhost__default_value[] = "::";
@@ -187,7 +351,7 @@ static const protobuf_c_boolean nsjail__ns_jail_config__clone_newpid__default_va
 static const protobuf_c_boolean nsjail__ns_jail_config__clone_newipc__default_value = 1;
 static const protobuf_c_boolean nsjail__ns_jail_config__clone_newuts__default_value = 1;
 static const protobuf_c_boolean nsjail__ns_jail_config__clone_newcgroup__default_value = 0;
-static const ProtobufCFieldDescriptor nsjail__ns_jail_config__field_descriptors[39] = {
+static const ProtobufCFieldDescriptor nsjail__ns_jail_config__field_descriptors[40] = {
        {
         "mode",
         1,
@@ -656,6 +820,18 @@ static const ProtobufCFieldDescriptor nsjail__ns_jail_config__field_descriptors[
         0,                     /* flags */
         0, NULL, NULL          /* reserved1,reserved2, etc */
         },
+       {
+        "mount",
+        42,
+        PROTOBUF_C_LABEL_REPEATED,
+        PROTOBUF_C_TYPE_MESSAGE,
+        offsetof(Nsjail__NsJailConfig, n_mount),
+        offsetof(Nsjail__NsJailConfig, mount),
+        &nsjail__mount_pt__descriptor,
+        NULL,
+        0,                     /* flags */
+        0, NULL, NULL          /* reserved1,reserved2, etc */
+        },
 };
 
 static const unsigned nsjail__ns_jail_config__field_indices_by_name[] = {
@@ -679,6 +855,7 @@ static const unsigned nsjail__ns_jail_config__field_indices_by_name[] = {
        11,                     /* field[11] = log_level */
        7,                      /* field[7] = max_conns_per_ip */
        0,                      /* field[0] = mode */
+       39,                     /* field[39] = mount */
        15,                     /* field[15] = pass_fd */
        25,                     /* field[25] = persona_addr_compat_layout */
        28,                     /* field[28] = persona_addr_limit_3gb */
@@ -703,7 +880,7 @@ static const unsigned nsjail__ns_jail_config__field_indices_by_name[] = {
 static const ProtobufCIntRange nsjail__ns_jail_config__number_ranges[2 + 1] = {
        {1, 0},
        {6, 3},
-       {0, 39}
+       {0, 40}
 };
 
 const ProtobufCMessageDescriptor nsjail__ns_jail_config__descriptor = {
@@ -713,7 +890,7 @@ const ProtobufCMessageDescriptor nsjail__ns_jail_config__descriptor = {
        "Nsjail__NsJailConfig",
        "nsjail",
        sizeof(Nsjail__NsJailConfig),
-       39,
+       40,
        nsjail__ns_jail_config__field_descriptors,
        nsjail__ns_jail_config__field_indices_by_name,
        2, nsjail__ns_jail_config__number_ranges,
index 0e71b93207b67190378b10658fc69ab4032f41f0..f1ec50c4c3abe9ed353c46f838a90a6eeeb815ca 100644 (file)
@@ -13,6 +13,7 @@ PROTOBUF_C__BEGIN_DECLS
 #error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c.
 #endif
 typedef struct _Nsjail__IdMap Nsjail__IdMap;
+typedef struct _Nsjail__MountPt Nsjail__MountPt;
 typedef struct _Nsjail__NsJailConfig Nsjail__NsJailConfig;
 
 /* --- enums --- */
@@ -46,6 +47,22 @@ extern char nsjail__id_map__outside_id__default_value[];
  { PROTOBUF_C_MESSAGE_INIT (&nsjail__id_map__descriptor) \
     , nsjail__id_map__inside_id__default_value, nsjail__id_map__outside_id__default_value, 1u, 0 }
 
+struct _Nsjail__MountPt {
+       ProtobufCMessage base;
+       char *src;
+       char *dst;
+       char *fstype;
+       char *options;
+       protobuf_c_boolean is_bind;
+       protobuf_c_boolean is_ro;
+       protobuf_c_boolean has_is_dir;
+       protobuf_c_boolean is_dir;
+};
+extern char nsjail__mount_pt__options__default_value[];
+#define NSJAIL__MOUNT_PT__INIT \
+ { PROTOBUF_C_MESSAGE_INIT (&nsjail__mount_pt__descriptor) \
+    , NULL, NULL, NULL, nsjail__mount_pt__options__default_value, 0, 0, 0,0 }
+
 struct _Nsjail__NsJailConfig {
        ProtobufCMessage base;
        Nsjail__Mode mode;
@@ -93,13 +110,15 @@ struct _Nsjail__NsJailConfig {
        Nsjail__IdMap **uidmap;
        size_t n_gidmap;
        Nsjail__IdMap **gidmap;
+       size_t n_mount;
+       Nsjail__MountPt **mount;
 };
 extern char nsjail__ns_jail_config__hostname__default_value[];
 extern char nsjail__ns_jail_config__cwd__default_value[];
 extern char nsjail__ns_jail_config__bindhost__default_value[];
 #define NSJAIL__NS_JAIL_CONFIG__INIT \
  { PROTOBUF_C_MESSAGE_INIT (&nsjail__ns_jail_config__descriptor) \
-    , NSJAIL__MODE__ONCE, NULL, 0, nsjail__ns_jail_config__hostname__default_value, nsjail__ns_jail_config__cwd__default_value, 0u, nsjail__ns_jail_config__bindhost__default_value, 0u, 600u, 0, NULL, 0,0, 0, 0, 0, 0,NULL, 0, 0, 512ull, 0ull, 600ull, 1ull, 32ull, 0,0, 0,0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0,NULL, 0,NULL }
+    , NSJAIL__MODE__ONCE, NULL, 0, nsjail__ns_jail_config__hostname__default_value, nsjail__ns_jail_config__cwd__default_value, 0u, nsjail__ns_jail_config__bindhost__default_value, 0u, 600u, 0, NULL, 0,0, 0, 0, 0, 0,NULL, 0, 0, 512ull, 0ull, 600ull, 1ull, 32ull, 0,0, 0,0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0,NULL, 0,NULL, 0,NULL }
 
 /* Nsjail__IdMap methods */
 void nsjail__id_map__init(Nsjail__IdMap * message);
@@ -109,6 +128,14 @@ size_t nsjail__id_map__pack_to_buffer(const Nsjail__IdMap * message, ProtobufCBu
 Nsjail__IdMap *nsjail__id_map__unpack
     (ProtobufCAllocator * allocator, size_t len, const uint8_t * data);
 void nsjail__id_map__free_unpacked(Nsjail__IdMap * message, ProtobufCAllocator * allocator);
+/* Nsjail__MountPt methods */
+void nsjail__mount_pt__init(Nsjail__MountPt * message);
+size_t nsjail__mount_pt__get_packed_size(const Nsjail__MountPt * message);
+size_t nsjail__mount_pt__pack(const Nsjail__MountPt * message, uint8_t * out);
+size_t nsjail__mount_pt__pack_to_buffer(const Nsjail__MountPt * message, ProtobufCBuffer * buffer);
+Nsjail__MountPt *nsjail__mount_pt__unpack
+    (ProtobufCAllocator * allocator, size_t len, const uint8_t * data);
+void nsjail__mount_pt__free_unpacked(Nsjail__MountPt * message, ProtobufCAllocator * allocator);
 /* Nsjail__NsJailConfig methods */
 void nsjail__ns_jail_config__init(Nsjail__NsJailConfig * message);
 size_t nsjail__ns_jail_config__get_packed_size(const Nsjail__NsJailConfig * message);
@@ -123,6 +150,8 @@ void nsjail__ns_jail_config__free_unpacked
 
 typedef void (*Nsjail__IdMap_Closure)
  (const Nsjail__IdMap * message, void *closure_data);
+typedef void (*Nsjail__MountPt_Closure)
+ (const Nsjail__MountPt * message, void *closure_data);
 typedef void (*Nsjail__NsJailConfig_Closure)
  (const Nsjail__NsJailConfig * message, void *closure_data);
 
@@ -133,6 +162,7 @@ typedef void (*Nsjail__NsJailConfig_Closure)
 extern const ProtobufCEnumDescriptor nsjail__mode__descriptor;
 extern const ProtobufCEnumDescriptor nsjail__log_level__descriptor;
 extern const ProtobufCMessageDescriptor nsjail__id_map__descriptor;
+extern const ProtobufCMessageDescriptor nsjail__mount_pt__descriptor;
 extern const ProtobufCMessageDescriptor nsjail__ns_jail_config__descriptor;
 
 PROTOBUF_C__END_DECLS
index 0f1ae4bf61ced6cbaebd7cc89b0dbfa8a4221682..9372699f9c32889948ba28b27ecfc1edd265aa25 100644 (file)
@@ -24,6 +24,16 @@ message IdMap {
        required bool use_newidmap = 4 [default = false];
 }
 
+message MountPt {
+       required string src = 1;
+       required string dst = 2;
+       required string fstype = 3;
+       required string options = 4 [default = ""];
+       required bool is_bind = 5 [default = false];
+       required bool is_ro = 6 [default = false];
+       optional bool is_dir = 7;
+}
+
 message NsJailConfig {
        required Mode mode = 1 [default = ONCE];
        optional string chroot_dir = 2;
@@ -70,4 +80,6 @@ message NsJailConfig {
 
        repeated IdMap uidmap = 40;
        repeated IdMap gidmap = 41;
+
+       repeated MountPt mount = 42;
 }
diff --git a/util.c b/util.c
index e41690a6ad54baccc4ffc213d5b2b104d9bbb95f..58c7f980568d2e5b30d7420e1fa84cbd97a9723c 100644 (file)
--- a/util.c
+++ b/util.c
@@ -43,6 +43,13 @@ void *utilMalloc(size_t sz)
        return ret;
 }
 
+void *utilCalloc(size_t sz)
+{
+       void *r = utilMalloc(sz);
+       memset(r, '\0', sz);
+       return r;
+}
+
 char *utilStrDup(const char *str)
 {
        char *ret = strdup(str);
diff --git a/util.h b/util.h
index ed7fb81f61746d955321511257855d9fbd2e24bb..00199d87b77859c84bdbc6ebda5d6774a58c0e86 100644 (file)
--- a/util.h
+++ b/util.h
@@ -28,6 +28,7 @@
 #include "common.h"
 
 void *utilMalloc(size_t sz);
+void *utilCalloc(size_t sz);
 char *utilStrDup(const char *str);
 char *utilStrDupLen(const char *str, size_t len);
 ssize_t utilReadFromFd(int fd, void *buf, size_t len);