aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Reid <dgreid@chromium.org>2015-10-22 21:05:29 -0700
committerDylan Reid <dgreid@google.com>2015-10-29 10:00:10 -0700
commita14e08dad428aaa934687e3636a84ca7a9711de2 (patch)
treeede75448407284bc641c6889e2cd712808355010
parentd6aedee6f0cdc53ad11af4f297297803bf95c96f (diff)
downloadminijail-brillo-m7-mr-dev.tar.gz
minijail: Allow static binaries in a bind mount to runbrillo-m7-releasebrillo-m7-mr-devbrillo-m7-dev
A previous commit placed a restriction on running static binaries and using bind mounts. Remove that restriction by checking if the binary path is in a bind mount and rebasing the path on to the bind mount source path so that the executable can be accessed from outside the chroot. This is needed so bind mounts can be specified when running a statically linked init program for Android. BUG=b/25192613 TEST=security_Minijail0, run a static init with bind mounts. Change-Id: I801909df67c1bf18d48efcfd54c11aafe4c75e54 Signed-off-by: Dylan Reid <dgreid@google.com>
-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