config: allow skipping arguments in mount points
authorRobert Swiecki <robert@swiecki.net>
Sat, 27 May 2017 13:01:34 +0000 (15:01 +0200)
committerRobert Swiecki <robert@swiecki.net>
Sat, 27 May 2017 13:01:34 +0000 (15:01 +0200)
cmdline.c
config.c
config.pb-c.c
config.pb-c.h
config.proto
configs/config1.example
mount.c
util.c
util.h

index 41a4c7223f8b482878dfac0a55e6f1b4d6256d79..85bca46cc4fadcd1499cd7431def7e5ed6de4490 100644 (file)
--- a/cmdline.c
+++ b/cmdline.c
@@ -227,7 +227,8 @@ void cmdlineLogParams(struct nsjconf_t *nsjconf)
                TAILQ_FOREACH(p, &nsjconf->mountpts, pointers) {
                        LOG_I
                            ("Mount point: src:'%s' dst:'%s' type:'%s' flags:%s options:'%s' isDir:%s",
-                            p->src, p->dst, p->fs_type, mountFlagsToStr(p->flags), p->options,
+                            p->src ? p->src : "[NULL]", p->dst, p->fs_type ? p->fs_type : "[NULL]",
+                            mountFlagsToStr(p->flags), p->options ? p->options : "[NULL]",
                             p->isDir ? "True" : "False");
                }
        }
@@ -657,7 +658,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                        } break;
                case 'T':{
                                struct mounts_t *p = utilMalloc(sizeof(struct mounts_t));
-                               p->src = "none";
+                               p->src = NULL;
                                p->dst = optarg;
                                p->flags = 0;
                                p->options = cmdlineTmpfsSz;
@@ -739,7 +740,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
 
        if (nsjconf->mount_proc == true) {
                struct mounts_t *p = utilMalloc(sizeof(struct mounts_t));
-               p->src = "none";
+               p->src = NULL;
                p->dst = "/proc";
                p->flags = 0;
                if (nsjconf->is_root_rw == false) {
@@ -764,7 +765,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                TAILQ_INSERT_HEAD(&nsjconf->mountpts, p, pointers);
        } else {
                struct mounts_t *p = utilMalloc(sizeof(struct mounts_t));
-               p->src = "none";
+               p->src = NULL;
                p->dst = "/";
                p->flags = 0;
                p->options = "";
index 434329d405701b8e36b40e1dea7b5f4138fb3e26..c6932be663896273f868526b0826c51af54f54f2 100644 (file)
--- a/config.c
+++ b/config.c
@@ -61,9 +61,7 @@ static bool configParseInternal(struct nsjconf_t *nsjconf, Nsjail__NsJailConfig
                LOG_E("Uknown running mode: %d", njc->mode);
                return false;
        }
-       if (njc->chroot_dir) {
-               nsjconf->chroot = utilStrDup(njc->chroot_dir);
-       }
+       nsjconf->chroot = utilStrDup(njc->chroot_dir);
        nsjconf->hostname = utilStrDup(njc->hostname);
        nsjconf->cwd = utilStrDup(njc->cwd);
        nsjconf->bindhost = utilStrDup(njc->bindhost);
@@ -71,9 +69,7 @@ static bool configParseInternal(struct nsjconf_t *nsjconf, Nsjail__NsJailConfig
        nsjconf->tlimit = njc->time_limit;
        nsjconf->daemonize = njc->daemon;
 
-       if (njc->log_file) {
-               nsjconf->logfile = utilStrDup(njc->log_file);
-       }
+       nsjconf->logfile = utilStrDup(njc->log_file);
        if (njc->has_log_level) {
                switch (njc->log_level) {
                case NSJAIL__LOG_LEVEL__DEBUG:
@@ -196,7 +192,9 @@ static bool configParseInternal(struct nsjconf_t *nsjconf, Nsjail__NsJailConfig
                if (njc->mount[i]->has_is_dir) {
                        p->isDir = njc->mount[i]->is_dir;
                } else {
-                       if (njc->mount[i]->is_bind) {
+                       if (njc->mount[i]->src == NULL) {
+                               p->isDir = true;
+                       } else if (njc->mount[i]->is_bind) {
                                p->isDir = mountIsDir(njc->mount[i]->src);
                        } else {
                                p->isDir = true;
@@ -214,9 +212,7 @@ static bool configParseInternal(struct nsjconf_t *nsjconf, Nsjail__NsJailConfig
                        return false;
                }
        }
-       if (njc->seccomp_string) {
-               nsjconf->kafel_string = utilStrDup(njc->seccomp_string);
-       }
+       nsjconf->kafel_string = utilStrDup(njc->seccomp_string);
 
        nsjconf->cgroup_mem_max = njc->cgroup_mem_max;
        nsjconf->cgroup_mem_mount = utilStrDup(njc->cgroup_mem_mount);
@@ -227,9 +223,7 @@ static bool configParseInternal(struct nsjconf_t *nsjconf, Nsjail__NsJailConfig
        nsjconf->cgroup_pids_parent = utilStrDup(njc->cgroup_pids_parent);
 
        nsjconf->iface_no_lo = njc->iface_no_lo;
-       if (njc->macvlan_iface) {
-               nsjconf->iface = utilStrDup(njc->macvlan_iface);
-       }
+       nsjconf->iface = utilStrDup(njc->macvlan_iface);
        nsjconf->iface_vs_ip = utilStrDup(njc->macvlan_vs_ip);
        nsjconf->iface_vs_nm = utilStrDup(njc->macvlan_vs_nm);
        nsjconf->iface_vs_gw = utilStrDup(njc->macvlan_vs_gw);
index de0c45580dfe190191104a8a0e827b3e41c2a40d..26fba15aec033416dfef15153018b595e349039e 100644 (file)
@@ -7,26 +7,22 @@
 #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);
 }
@@ -37,32 +33,27 @@ 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__mount_pt__init(Nsjail__MountPt * 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)
-{
+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)
-{
+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)
-{
+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);
 }
@@ -73,62 +64,52 @@ Nsjail__MountPt *nsjail__mount_pt__unpack
            protobuf_c_message_unpack(&nsjail__mount_pt__descriptor, allocator, len, data);
 }
 
-void nsjail__mount_pt__free_unpacked(Nsjail__MountPt * message, ProtobufCAllocator * allocator)
-{
+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__exe__init(Nsjail__Exe * message)
-{
+void nsjail__exe__init(Nsjail__Exe * message) {
        static Nsjail__Exe init_value = NSJAIL__EXE__INIT;
        *message = init_value;
 }
 
-size_t nsjail__exe__get_packed_size(const Nsjail__Exe * message)
-{
+size_t nsjail__exe__get_packed_size(const Nsjail__Exe * message) {
        assert(message->base.descriptor == &nsjail__exe__descriptor);
        return protobuf_c_message_get_packed_size((const ProtobufCMessage *)(message));
 }
 
-size_t nsjail__exe__pack(const Nsjail__Exe * message, uint8_t * out)
-{
+size_t nsjail__exe__pack(const Nsjail__Exe * message, uint8_t * out) {
        assert(message->base.descriptor == &nsjail__exe__descriptor);
        return protobuf_c_message_pack((const ProtobufCMessage *)message, out);
 }
 
-size_t nsjail__exe__pack_to_buffer(const Nsjail__Exe * message, ProtobufCBuffer * buffer)
-{
+size_t nsjail__exe__pack_to_buffer(const Nsjail__Exe * message, ProtobufCBuffer * buffer) {
        assert(message->base.descriptor == &nsjail__exe__descriptor);
        return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *)message, buffer);
 }
 
-Nsjail__Exe *nsjail__exe__unpack(ProtobufCAllocator * allocator, size_t len, const uint8_t * data)
-{
+Nsjail__Exe *nsjail__exe__unpack(ProtobufCAllocator * allocator, size_t len, const uint8_t * data) {
        return (Nsjail__Exe *)
            protobuf_c_message_unpack(&nsjail__exe__descriptor, allocator, len, data);
 }
 
-void nsjail__exe__free_unpacked(Nsjail__Exe * message, ProtobufCAllocator * allocator)
-{
+void nsjail__exe__free_unpacked(Nsjail__Exe * message, ProtobufCAllocator * allocator) {
        assert(message->base.descriptor == &nsjail__exe__descriptor);
        protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator);
 }
 
-void nsjail__ns_jail_config__init(Nsjail__NsJailConfig * message)
-{
+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);
 }
@@ -240,7 +221,7 @@ static const ProtobufCFieldDescriptor nsjail__mount_pt__field_descriptors[7] = {
        {
         "src",
         1,
-        PROTOBUF_C_LABEL_REQUIRED,
+        PROTOBUF_C_LABEL_OPTIONAL,
         PROTOBUF_C_TYPE_STRING,
         0,                     /* quantifier_offset */
         offsetof(Nsjail__MountPt, src),
@@ -264,7 +245,7 @@ static const ProtobufCFieldDescriptor nsjail__mount_pt__field_descriptors[7] = {
        {
         "fstype",
         3,
-        PROTOBUF_C_LABEL_REQUIRED,
+        PROTOBUF_C_LABEL_OPTIONAL,
         PROTOBUF_C_TYPE_STRING,
         0,                     /* quantifier_offset */
         offsetof(Nsjail__MountPt, fstype),
index b48c57d304990d7dfa368256c4e74280f292fef7..302aa387085634ff771a3ccb655ad7995fb20518 100644 (file)
@@ -75,7 +75,7 @@ extern char nsjail__id_map__outside_id__default_value[];
 struct _Nsjail__MountPt {
        ProtobufCMessage base;
        /*
-        * Can be empty string for filesystems like 'proc' 
+        * Can be skipped for filesystems like 'proc' 
         */
        char *src;
        char *dst;
@@ -130,7 +130,7 @@ struct _Nsjail__NsJailConfig {
         */
        Nsjail__Mode mode;
        /*
-        * Equivalent to a mount with dst='/' 
+        * Equivalent to a bind mount with src='/', dst='/' 
         */
        char *chroot_dir;
        /*
index d5f37309aecae084742ce6abe8b04b29157f44b3..6f9286709777a3f51b303ea5d8b2319306ad75f2 100644 (file)
@@ -27,11 +27,11 @@ message IdMap
 }
 message MountPt
 {
-    /* Can be empty string for filesystems like 'proc' */
-    required string src = 1;
+    /* Can be skipped for filesystems like 'proc' */
+    optional string src = 1;
     required string dst = 2;
     /* Can be empty for mount --bind mounts */
-    required string fstype = 3;
+    optional string fstype = 3 [ default = "" ];
     /* E.g. size=5000000 for 'tmpfs' */
     required string options = 4 [ default = "" ];
     /* Is it 'mount --bind src dst' type of mount */
@@ -53,7 +53,7 @@ message NsJailConfig
 {
     /* Execution mode: see 'msg Mode' description for more */
     required Mode mode = 1 [ default = ONCE ];
-    /* Equivalent to a mount with dst='/' */
+    /* Equivalent to a bind mount with src='/', dst='/' */
     optional string chroot_dir = 2;
     /* Applies both to the chroot_dir and to /proc mounts */
     required bool is_root_rw = 3 [ default = false ];
index 30d273b674f5bc538016b522b34159562048fb96..096b29bb89a8718e8fdbe21cd46db17601b32553 100644 (file)
@@ -1,8 +1,6 @@
 mode: ONCE
-chroot_dir: "/"
-is_root_rw: false
 hostname: "TEST-NS"
-cwd: "/lib"
+cwd: "/"
 
 bindhost: "::1"
 max_conns_per_ip: 10
@@ -14,6 +12,7 @@ daemon: false
 keep_env: false
 envar: "ENVAR1=VALUE1"
 envar: "ENVAR2=VALUE2"
+envar: "PS1=[INSIDE-JAIL]: "
 
 silent: false
 skip_setsid: false
@@ -56,19 +55,58 @@ gidmap {
 }
 
 mount {
-       src: ""
+       src: "/lib"
+       dst: "/lib"
+       is_bind: true
+       is_ro: true
+}
+
+mount {
+       src: "/bin"
+       dst: "/bin"
+       is_bind: true
+       is_ro: true
+}
+
+mount {
+       src: "/usr"
+       dst: "/usr"
+       is_bind: true
+       is_ro: true
+}
+
+mount {
+       src: "/bin"
+       dst: "/bin"
+       is_bind: true
+       is_ro: true
+}
+
+mount {
+       src: "/sbin"
+       dst: "/sbin"
+       is_bind: true
+       is_ro: true
+}
+
+mount {
+       src: "/lib64"
+       dst: "/lib64"
+       is_bind: true
+       is_ro: true
+}
+
+mount {
        dst: "/tmp"
        fstype: "tmpfs"
-       options: ""
        is_ro: false
        is_bind: false
 }
 
 mount {
-       src: ""
        dst: "/dev"
        fstype: "tmpfs"
-       options: ""
+       options: "size=8388608"
        is_ro: false
        is_bind: false
 }
@@ -76,12 +114,18 @@ mount {
 mount {
        src: "/dev/null"
        dst: "/dev/null"
-       fstype: ""
-       options: ""
        is_ro: false
        is_bind: true
 }
 
+mount {
+       dst: "/proc"
+       fstype: "proc"
+       is_ro: true
+}
+
+mount_proc: false
+
 seccomp_string: "
        POLICY example {
                ERRNO(1337) { geteuid },
@@ -91,6 +135,6 @@ seccomp_string: "
 "
 
 exec_bin {
-       path: "/usr/bin/id"
-       arg: "root"
+       path: "/bin/bash"
+       arg: "-i"
 }
diff --git a/mount.c b/mount.c
index 03c3887bf234223ea189e5523ca9fbe893b8d00c..2fe5891d7d3d96426da1827414ce82f62623faf5 100644 (file)
--- a/mount.c
+++ b/mount.c
@@ -120,13 +120,16 @@ bool mountIsDir(const char *path)
 static bool mountMount(struct nsjconf_t *nsjconf, struct mounts_t *mpt, const char *oldroot,
                       const char *dst)
 {
-       LOG_D("Mounting '%s' on '%s' (type:'%s', flags:%s, options:'%s', is_dir:%s)", mpt->src, dst,
-             mpt->fs_type, mountFlagsToStr(mpt->flags), mpt->options,
+       LOG_D("Mounting '%s' on '%s' (type:'%s', flags:%s, options:'%s', is_dir:%s)",
+             mpt->src ? mpt->src : "[NULL]", dst, mpt->fs_type ? mpt->fs_type : "[NULL]",
+             mountFlagsToStr(mpt->flags), mpt->options ? mpt->options : "[NULL]",
              mpt->isDir ? "True" : "False");
 
-       char srcpath[PATH_MAX] = { 0 };
-       if (mpt->src != NULL) {
+       char srcpath[PATH_MAX];
+       if (mpt->src != NULL && strlen(mpt->src) > 0) {
                snprintf(srcpath, sizeof(srcpath), "%s/%s", oldroot, mpt->src);
+       } else {
+               snprintf(srcpath, sizeof(srcpath), "none");
        }
 
        if (mpt->isDir == true) {
diff --git a/util.c b/util.c
index 58c7f980568d2e5b30d7420e1fa84cbd97a9723c..5e0cc2f2db7cc36d07e5539d9ba7c38b768462a6 100644 (file)
--- a/util.c
+++ b/util.c
@@ -52,6 +52,9 @@ void *utilCalloc(size_t sz)
 
 char *utilStrDup(const char *str)
 {
+       if (str == NULL) {
+               return NULL;
+       }
        char *ret = strdup(str);
        if (ret == NULL) {
                LOG_E("Cannot allocate memory for strdup(sz=%zu)", strlen(str));
diff --git a/util.h b/util.h
index 00199d87b77859c84bdbc6ebda5d6774a58c0e86..d438bcd9656ad40ed8d2575b8a91a5de1971e8df 100644 (file)
--- a/util.h
+++ b/util.h
@@ -30,7 +30,6 @@
 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);
 ssize_t utilReadFromFile(const char *fname, void *buf, size_t len);
 ssize_t utilWriteToFd(int fd, const void *buf, size_t len);