Allow to create symlinks
authorRobert Swiecki <robert@swiecki.net>
Wed, 28 Jun 2017 22:32:20 +0000 (00:32 +0200)
committerRobert Swiecki <robert@swiecki.net>
Wed, 28 Jun 2017 22:32:20 +0000 (00:32 +0200)
cmdline.c
common.h
config.c
config.proto
configs/bash-with-fake-geteuid.cfg
mount.c
mount.h

index ffdf4f2cb0b3c3c56716017f18f7989e1e52ae84..7d297bd7ed8c483f8315b468ef865f0f63856b8b 100644 (file)
--- a/cmdline.c
+++ b/cmdline.c
@@ -624,6 +624,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                                p->options = "";
                                p->fs_type = "";
                                p->isDir = mountIsDir(optarg);
+                               p->isSymlink = false;
                                p->mandatory = true;
                                TAILQ_INSERT_TAIL(&nsjconf->mountpts, p, pointers);
                        } break;
@@ -638,6 +639,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                                p->options = "";
                                p->fs_type = "";
                                p->isDir = mountIsDir(optarg);
+                               p->isSymlink = false;
                                p->mandatory = true;
                                TAILQ_INSERT_TAIL(&nsjconf->mountpts, p, pointers);
                        } break;
@@ -651,6 +653,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                                p->options = cmdlineTmpfsSz;
                                p->fs_type = "tmpfs";
                                p->isDir = true;
+                               p->isSymlink = false;
                                p->mandatory = true;
                                TAILQ_INSERT_TAIL(&nsjconf->mountpts, p, pointers);
                        } break;
@@ -739,6 +742,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                p->options = "";
                p->fs_type = "proc";
                p->isDir = true;
+               p->isSymlink = false;
                p->mandatory = true;
                TAILQ_INSERT_HEAD(&nsjconf->mountpts, p, pointers);
        }
@@ -755,6 +759,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                p->options = "";
                p->fs_type = "";
                p->isDir = true;
+               p->isSymlink = false;
                p->mandatory = true;
                TAILQ_INSERT_HEAD(&nsjconf->mountpts, p, pointers);
        } else {
@@ -770,6 +775,7 @@ bool cmdlineParse(int argc, char *argv[], struct nsjconf_t * nsjconf)
                p->options = "";
                p->fs_type = "tmpfs";
                p->isDir = true;
+               p->isSymlink = false;
                p->mandatory = true;
                TAILQ_INSERT_HEAD(&nsjconf->mountpts, p, pointers);
        }
index 500d97209177ac301f6866d69a5eb02e99757dc3..5638d6c1d5afac8d2b7522f91b7aa37e9c75a43f 100644 (file)
--- a/common.h
+++ b/common.h
@@ -73,6 +73,7 @@ struct mounts_t {
        const char *options;
        uintptr_t flags;
        bool isDir;
+       bool isSymlink;
        bool mandatory;
         TAILQ_ENTRY(mounts_t) pointers;
 };
index a1c9b411f76ec6be3cd52fb37ab7c4207edd7019..4b1d5a50d6239dcf84c76c308b31fa41a06e2e6e 100644 (file)
--- a/config.c
+++ b/config.c
@@ -202,7 +202,7 @@ static bool configParseInternal(struct nsjconf_t *nsjconf, Nsjail__NsJailConfig
 
                if (mountAddMountPt
                    (nsjconf, src, dst, fstype, options, flags, isDir, mandatory, src_env,
-                    dst_env, src_content, src_content_len) == false) {
+                    dst_env, src_content, src_content_len, njc->mount[i]->is_symlink) == false) {
                        LOG_E("Couldn't add mountpoint for src:'%s' dst:'%s'", src, dst);
                        return false;
                }
index cf9816db00e95829d83477f92dd7b31d1fc71aeb..9851036a5ad1dfd040f0ef13992fef747381ed14 100644 (file)
@@ -51,6 +51,8 @@ message MountPt
     optional bool is_dir = 10;
     /* Should the sandboxing fail if we cannot mount this resource? */
     required bool mandatory = 11 [ default = true ];
+       /* Is it a symlink (instead of real mount point)? */
+       required bool is_symlink = 12 [ default = false ];
 }
 message Exe
 {
index 5a4667be854b0c6ccb8bcb193d87a69fb320ec95..59dfb03023fc96d6f67654d83d3ae05fae5cab6b 100644 (file)
@@ -129,6 +129,12 @@ mount {
        is_bind: false
 }
 
+mount {
+       src: "/proc/self/fd"
+       dst: "/dev/fd"
+       is_symlink: true
+}
+
 mount {
        src: "/dev/null"
        dst: "/dev/null"
@@ -156,7 +162,6 @@ mount {
 
 seccomp_string: "
        POLICY example {
-               ERRNO(1337) { geteuid },
                KILL { syslog },
                ERRNO(0) { ptrace }
        }
diff --git a/mount.c b/mount.c
index 1f54d55f17c2249ac709c886abb2c6138ec65344..cfc0f25d41eb6d0a4089cb05fb348c4fe74b6b5e 100644 (file)
--- a/mount.c
+++ b/mount.c
@@ -122,7 +122,7 @@ static bool mountMount(struct mounts_t *mpt, const char *newroot, const char *tm
        char dst[PATH_MAX];
        snprintf(dst, sizeof(dst), "%s/%s", newroot, mpt->dst);
 
-       LOG_D("Mounting '%s'", mountDescribeMountPt(mpt));
+       LOG_D("mounting '%s'", mountDescribeMountPt(mpt));
 
        char srcpath[PATH_MAX];
        if (mpt->src != NULL && strlen(mpt->src) > 0) {
@@ -131,7 +131,12 @@ static bool mountMount(struct mounts_t *mpt, const char *newroot, const char *tm
                snprintf(srcpath, sizeof(srcpath), "none");
        }
 
-       if (mpt->isDir == true) {
+       if (mpt->isSymlink == true) {
+               if (utilCreateDirRecursively(dst) == false) {
+                       LOG_W("Couldn't create upper directories for '%s'", dst);
+                       return false;
+               }
+       } else if (mpt->isDir == true) {
                if (utilCreateDirRecursively(dst) == false) {
                        LOG_W("Couldn't create upper directories for '%s'", dst);
                        return false;
@@ -152,6 +157,15 @@ static bool mountMount(struct mounts_t *mpt, const char *newroot, const char *tm
                }
        }
 
+       if (mpt->isSymlink == true) {
+               LOG_D("symlink('%s', '%s')", srcpath, dst);
+               if (symlink(srcpath, dst) == -1) {
+                       PLOG_W("symlink('%s', '%s')", srcpath, dst);
+                       return false;
+               }
+               return true;
+       }
+
        if (mpt->src_content) {
                snprintf(srcpath, sizeof(srcpath), "%s/file.XXXXXX", tmpdir);
                int fd = mkostemp(srcpath, O_CLOEXEC);
@@ -198,6 +212,9 @@ static bool mountMount(struct mounts_t *mpt, const char *newroot, const char *tm
 
 static bool mountRemountRO(struct mounts_t *mpt)
 {
+       if (mpt->isSymlink == true) {
+               return true;
+       }
        if (!(mpt->flags & MS_RDONLY)) {
                return true;
        }
@@ -379,7 +396,7 @@ bool mountInitNs(struct nsjconf_t * nsjconf)
 bool mountAddMountPt(struct nsjconf_t * nsjconf, const char *src, const char *dst,
                     const char *fstype, const char *options, uintptr_t flags, const bool * isDir,
                     bool mandatory, const char *src_env, const char *dst_env,
-                    const uint8_t * src_content, size_t src_content_len)
+                    const uint8_t * src_content, size_t src_content_len, bool is_symlink)
 {
        struct mounts_t *p = utilCalloc(sizeof(struct mounts_t));
 
@@ -430,6 +447,7 @@ bool mountAddMountPt(struct nsjconf_t * nsjconf, const char *src, const char *ds
        p->options = utilStrDup(options);
        p->flags = flags;
        p->isDir = true;
+       p->isSymlink = is_symlink;
        p->mandatory = mandatory;
 
        if (isDir) {
@@ -471,6 +489,9 @@ const char *mountDescribeMountPt(struct mounts_t *mpt)
                utilSSnPrintf(mount_pt_descr, sizeof(mount_pt_descr), " src_content_len:%zu",
                              mpt->src_content_len);
        }
+       if (mpt->isSymlink) {
+               utilSSnPrintf(mount_pt_descr, sizeof(mount_pt_descr), " symlink:true");
+       }
 
        return mount_pt_descr;
 }
diff --git a/mount.h b/mount.h
index fa4f4246ffa7b07b59221e0c2ac34bd9fc73d756..a7fd94810eb3862fee8cf275b79533ecf99a0c54 100644 (file)
--- a/mount.h
+++ b/mount.h
@@ -32,7 +32,7 @@ bool mountInitNs(struct nsjconf_t *nsjconf);
 bool mountAddMountPt(struct nsjconf_t *nsjconf, const char *src, const char *dst,
                     const char *fstype, const char *options, uintptr_t flags, const bool * isDir,
                     bool mandatory, const char *src_env, const char *dst_env,
-                    const uint8_t * src_content, size_t src_content_len);
+                    const uint8_t * src_content, size_t src_content_len, bool is_symlink);
 const char *mountDescribeMountPt(struct mounts_t *mpt);
 
 #endif                         /* NS_MOUNT_H */