aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libminijail.c58
-rw-r--r--minijail0.c13
2 files changed, 51 insertions, 20 deletions
diff --git a/libminijail.c b/libminijail.c
index bebdb8c..47b4b3f 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -387,20 +387,60 @@ int API minijail_enter_pivot_root(struct minijail *j, const char *dir)
return 0;
}
-char *minijail_get_original_path(struct minijail *j, const char *chroot_path)
+static char *append_external_path(const char *external_path,
+ const char *path_inside_chroot)
{
- char *external_path;
+ char *path;
size_t pathlen;
- if (!j->chrootdir)
- return strdup(chroot_path);
-
/* One extra char for '/' and one for '\0', hence + 2. */
- pathlen = strlen(chroot_path) + strlen(j->chrootdir) + 2;
- external_path = malloc(pathlen);
- snprintf(external_path, pathlen, "%s/%s", j->chrootdir, chroot_path);
+ pathlen = strlen(path_inside_chroot) + strlen(external_path) + 2;
+ path = malloc(pathlen);
+ snprintf(path, pathlen, "%s/%s", external_path, path_inside_chroot);
+
+ return path;
+}
+
+char API *minijail_get_original_path(struct minijail *j,
+ const char *path_inside_chroot)
+{
+ struct binding *b;
+
+ b = j->bindings_head;
+ while (b) {
+ /*
+ * If |path_inside_chroot| is the exact destination of a
+ * bind mount, then the original path is exactly the source of
+ * the bind mount.
+ * for example: "-b /some/path/exe,/chroot/path/exe"
+ * bind source = /some/path/exe, bind dest = /chroot/path/exe
+ * Then when getting the original path of "/chroot/path/exe",
+ * the source of that bind mount, "/some/path/exe" is what
+ * should be returned.
+ */
+ if (!strcmp(b->dest, path_inside_chroot))
+ return strdup(b->src);
+
+ /*
+ * If |path_inside_chroot| is within the destination path of a
+ * bind mount, take the suffix of the chroot path relative to
+ * the bind mount destination path, and append it to the bind
+ * mount source path.
+ */
+ if (!strncmp(b->dest, path_inside_chroot, strlen(b->dest))) {
+ const char *relative_path =
+ path_inside_chroot + strlen(b->dest);
+ return append_external_path(b->src, relative_path);
+ }
+ b = b->next;
+ }
+
+ /* If there is a chroot path, append |path_inside_chroot| to that. */
+ if (j->chrootdir)
+ return append_external_path(j->chrootdir, path_inside_chroot);
- return external_path;
+ /* No chroot, so the path outside is the same as it is inside. */
+ return strdup(path_inside_chroot);
}
void API minijail_mount_tmp(struct minijail *j)
diff --git a/minijail0.c b/minijail0.c
index e272702..d1260bd 100644
--- a/minijail0.c
+++ b/minijail0.c
@@ -308,23 +308,14 @@ int main(int argc, char *argv[])
program_path = minijail_get_original_path(j, argv[0]);
/* Check that we can access the target program. */
- if (!minijail_has_bind_mounts(j) && access(program_path, X_OK)) {
+ if (access(program_path, X_OK)) {
fprintf(stderr, "Target program '%s' is not accessible.\n",
argv[0]);
return 1;
}
/* Check if target is statically or dynamically linked. */
- if (minijail_has_bind_mounts(j)) {
- /* We can't tell what the internal path to the binary is so
- * assume it's dynamically linked.
- */
- elftype = ELFDYNAMIC;
- warn("assuming program '%s' is dynamically linked\n", argv[0]);
- } else {
- elftype = get_elf_linkage(program_path);
- }
-
+ elftype = get_elf_linkage(program_path);
if (elftype == ELFSTATIC) {
/*
* Target binary is statically linked so we cannot use