summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Golle <daniel@makrotopia.org>2021-10-05 21:23:37 +0100
committerDaniel Golle <daniel@makrotopia.org>2021-10-13 00:35:49 +0100
commit324ebd0a3c983bd12b1b330e23293b9e1d64044f (patch)
treebbcb10757f54bb258fb99bdd3cf99141032d2b66
parent6398e0541a693df8a267b9ee77b9e96cbaf97abd (diff)
downloadprocd-324ebd0a3c983bd12b1b330e23293b9e1d64044f.tar.gz
jail: fs: add support for asymmetric mount bind
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>
-rw-r--r--jail/fs.c16
-rw-r--r--jail/fs.h8
-rw-r--r--jail/jail.c17
3 files changed, 33 insertions, 8 deletions
diff --git a/jail/fs.c b/jail/fs.c
index 210567e..c14027b 100644
--- 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;
diff --git a/jail/fs.h b/jail/fs.h
index 945b37d..541030f 100644
--- 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);
diff --git a/jail/jail.c b/jail/jail.c
index aabde52..ff54d97 100644
--- a/jail/jail.c
+++ b/jail/jail.c
@@ -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;