jail: fs: add support for asymmetric mount bind
authorDaniel Golle <daniel@makrotopia.org>
Tue, 5 Oct 2021 20:23:37 +0000 (21:23 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Tue, 12 Oct 2021 23:35:49 +0000 (00:35 +0100)
Allow mounting absolute path on host to defined mountpoint inside
container using ':' character in argument of '-r' and '-w' parameters.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
jail/fs.c
jail/fs.h
jail/jail.c

index 210567e79eab2f99863f93c2d38c567e92df255e..c14027b5ae948454aa247bb8372e72314aa81ddf 100644 (file)
--- a/jail/fs.c
+++ b/jail/fs.c
@@ -206,14 +206,19 @@ int add_mount_inner(const char *source, const char *target, const char *filesyst
        return _add_mount(source, target, filesystemtype, mountflags, propflags, optstr, error, true);
 }
 
-int add_mount_bind(const char *path, int readonly, int error)
+static int _add_mount_bind(const char *path, const char *path2, int readonly, int error)
 {
        unsigned long mountflags = MS_BIND;
 
        if (readonly)
                mountflags |= MS_RDONLY;
 
-       return add_mount(path, path, NULL, mountflags, 0, NULL, error);
+       return add_mount(path, path2, NULL, mountflags, 0, NULL, error);
+}
+
+int add_mount_bind(const char *path, int readonly, int error)
+{
+       return _add_mount_bind(path, path, readonly, error);
 }
 
 enum {
@@ -478,9 +483,10 @@ static int add_script_interp(const char *path, const char *map, int size)
        return add_path_and_deps(buf, 1, -1, 0);
 }
 
-int add_path_and_deps(const char *path, int readonly, int error, int lib)
+int add_2paths_and_deps(const char *path, const char *path2, int readonly, int error, int lib)
 {
        assert(path != NULL);
+       assert(path2 != NULL);
 
        if (lib == 0 && path[0] != '/') {
                ERROR("%s is not an absolute path\n", path);
@@ -490,12 +496,12 @@ int add_path_and_deps(const char *path, int readonly, int error, int lib)
        char *map = NULL;
        int fd, ret = -1;
        if (path[0] == '/') {
-               if (avl_find(&mounts, path))
+               if (avl_find(&mounts, path2))
                        return 0;
                fd = open(path, O_RDONLY|O_CLOEXEC);
                if (fd < 0)
                        return error;
-               add_mount_bind(path, readonly, error);
+               _add_mount_bind(path, path2, readonly, error);
        } else {
                if (avl_find(&libraries, path))
                        return 0;
index 945b37db83f6c3de4f859b5c84387ee763e3d800..541030f7eb7c2046e18bc1fc554601f04e29768a 100644 (file)
--- a/jail/fs.h
+++ b/jail/fs.h
@@ -22,7 +22,13 @@ int add_mount_inner(const char *source, const char *target, const char *filesyst
              unsigned long mountflags, unsigned long propflags, const char *optstr, int error);
 int add_mount_bind(const char *path, int readonly, int error);
 int parseOCImount(struct blob_attr *msg);
-int add_path_and_deps(const char *path, int readonly, int error, int lib);
+int add_2paths_and_deps(const char *path, const char *path2, int readonly, int error, int lib);
+
+static inline int add_path_and_deps(const char *path, int readonly, int error, int lib)
+{
+       return add_2paths_and_deps(path, path, readonly, error, lib);
+}
+
 int mount_all(const char *jailroot);
 void mount_list_init(void);
 void mount_free(void);
index aabde52cbd1c861b8aecb0d27d8fa91dc0854799..ff54d970b6953a1539910bda1327007c43641f04 100644 (file)
@@ -2568,6 +2568,7 @@ int main(int argc, char **argv)
        const char ubus[] = "/var/run/ubus/ubus.sock";
        int ret = EXIT_FAILURE;
        int ch;
+       char *tmp;
 
        if (uid) {
                ERROR("not root, aborting: %m\n");
@@ -2643,11 +2644,23 @@ int main(int argc, char **argv)
                        break;
                case 'r':
                        opts.namespace |= CLONE_NEWNS;
-                       add_path_and_deps(optarg, 1, 0, 0);
+                       tmp = strchr(optarg, ':');
+                       if (tmp) {
+                               *(tmp++) = '\0';
+                               add_2paths_and_deps(optarg, tmp, 1, 0, 0);
+                       } else {
+                               add_path_and_deps(optarg, 1, 0, 0);
+                       }
                        break;
                case 'w':
                        opts.namespace |= CLONE_NEWNS;
-                       add_path_and_deps(optarg, 0, 0, 0);
+                       tmp = strchr(optarg, ':');
+                       if (tmp) {
+                               *(tmp++) = '\0';
+                               add_2paths_and_deps(optarg, tmp, 0, 0, 0);
+                       } else {
+                               add_path_and_deps(optarg, 0, 0, 0);
+                       }
                        break;
                case 'u':
                        opts.namespace |= CLONE_NEWNS;