libminijail: move over to using marshalled binary for preload
Move libminijail and libminijailpreload over to using the marshalling
helper functions and add to/from_fd. The format itself is not terribly
robust, but we can change it underneath the functions in the future
(or move struct minijail to a protobuf :).
These changes lay the groundwork for sending seccomp_filter policy. A
subsequent change will implement that and disable use in the parent.
BUG=chromium-os:19459
TEST=tested as per previous commits:
minijail0 -[pvrcuGg] -- /bin/cat /proc/self/status
.. /bin/ps aux
.. /bin/bash -c 'env'
Change-Id: I565816611b31ce49f85fee2241c55a3328d7b770
Reviewed-on: http://gerrit.chromium.org/gerrit/7892
Reviewed-by: Elly Jones <[email protected]>
Tested-by: Will Drewry <[email protected]>
diff --git a/libminijailpreload.c b/libminijailpreload.c
index a4970bc..fb74e93 100644
--- a/libminijailpreload.c
+++ b/libminijailpreload.c
@@ -34,11 +34,6 @@
envp[i][0] = '\0';
}
-static void splitarg(char *str, char **key, char **val) {
- *key = strsep(&str, "=");
- *val = strsep(&str, "");
-}
-
/** @brief Fake main(), spliced in before the real call to main() by
* __libc_start_main (see below).
* We get serialized commands from our invoking process over an fd specified
@@ -48,10 +43,7 @@
*/
static int fake_main(int argc, char **argv, char **envp) {
char *fd_name = getenv(kFdEnvVar);
- char *arg = NULL;
- size_t arg_len;
int fd = -1;
- FILE *args;
struct minijail *j;
if (geteuid() != getuid() || getegid() != getgid())
/* If we didn't do this check, an attacker could set kFdEnvVar for
@@ -64,43 +56,20 @@
fd = atoi(fd_name);
if (fd < 0)
return MINIJAIL_ERR_PRELOAD;
- args = fdopen(fd, "r");
- if (!args)
- return MINIJAIL_ERR_PRELOAD;
j = minijail_new();
if (!j)
die("preload: out of memory");
- while (getline(&arg, &arg_len, args) > 0) {
- char *key, *val;
- unsigned long v;
- splitarg(arg, &key, &val);
- if (!strcmp(arg, "eom\n")) {
- break;
- } else if (!strcmp(key, "caps")) {
- v = strtoul(val, NULL, 16);
- minijail_use_caps(j, v);
- } else if (!strcmp(key, "ptrace")) {
- minijail_disable_ptrace(j);
- } else if (!strcmp(key, "uid")) {
- v = atoi(val);
- minijail_change_uid(j, v);
- } else if (!strcmp(key, "gid")) {
- v = atoi(val);
- minijail_change_gid(j, v);
- } else if (!strcmp(key, "seccomp")) {
- minijail_use_seccomp(j);
- }
- free(arg);
- arg = NULL;
- }
- if (!feof(args) && ferror(args))
- die("preload: unexpected failure during unmarshalling");
- fclose(args);
+ if (minijail_from_fd(fd, j))
+ die("preload: failed to parse minijail from parent");
+ close(fd);
+
/* TODO(ellyjones): this trashes existing preloads, so one can't do:
* LD_PRELOAD="/tmp/test.so libminijailpreload.so" prog; the descendants of
* prog will have no LD_PRELOAD set at all. */
unset_in_env(envp, kLdPreloadEnvVar);
+ /* Strip out flags meant for the parent. */
+ minijail_preenter(j);
minijail_enter(j);
minijail_destroy(j);
dlclose(libc_handle);