libminijailpreload: proper env cleaning
We add two utility functions in util.c:
- minijail_unsetenv, which removes a var from a given envp array
- minijail_getenv, which returns a var value from a given envp array
(same as getenv but working on an arbitrary array)
And a static utility function in util.c:
- getenv_index, which returns the index number of a passed variable
name, or the size of the passed array if not found
It's used by the above two utility functions, and has also been
integrated to minijail_setenv
And use them in libminijailpreload.c to:
- properly remove the minijail-injected .so in LD_PRELOAD, without
completely trashing any preexisting LD_PRELOAD, as was done before
in the code. A static func truncate_preload_env() only existing in
libminijailpreload.c is tasked to do this, and
- properly remove the __MINIJAIL_FD (kFdEnvVar) internal variable from
the child environment before spawning it. Before, this was done by
zeroing the proper envp entry, which is flagged as being an invalid
environment by some programs, such as the MongoDB official client:
Without minijail:
$ /tmp/m/bin/mongo --help >/dev/null; echo $?
0
$ env -i ./minijail0 /tmp/m/bin/mongo --help >/dev/null; echo $?
Failed global initialization: BadValue malformed environment block
libminijail[4045108]: child process 4045109 exited with status 1
1
With minijail, with this patch:
$ env -i ./minijail0 /tmp/m/bin/mongo --help >/dev/null; echo $?
0
This can also be seen using `env`:
Without minijail:
$ env -i /usr/bin/env | xxd
$
With minijail, before this patch:
$ env -i ./minijail0 /usr/bin/env | xxd
00000000: 0a0a ..
$
With minijail, with this patch:
$ env -i ./minijail0 /usr/bin/env | xxd
$
Change-Id: I79739a4c6f527c49a31ce31aaa9085fa574a25ee
diff --git a/util_unittest.cc b/util_unittest.cc
index 5bbc172..b9e6dfc 100644
--- a/util_unittest.cc
+++ b/util_unittest.cc
@@ -158,6 +158,42 @@
EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
dump_env(env));
+ EXPECT_EQ(nullptr, minijail_getenv(nullptr, "dup"));
+ EXPECT_EQ(nullptr, minijail_getenv(nullptr, nullptr));
+ EXPECT_EQ(nullptr, minijail_getenv(env, nullptr));
+ EXPECT_EQ(nullptr, minijail_getenv(env, "dup="));
+ EXPECT_EQ(nullptr, minijail_getenv(env, "du"));
+ EXPECT_EQ(std::string("8"), minijail_getenv(env, "new2"));
+ EXPECT_EQ(std::string("3"), minijail_getenv(env, "val1"));
+ EXPECT_EQ(std::string("5"), minijail_getenv(env, "dup"));
+
+ EXPECT_EQ(false, minijail_unsetenv(env, "nonexisting"));
+ EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
+ dump_env(env));
+ EXPECT_EQ(false, minijail_unsetenv(env, ""));
+ EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
+ dump_env(env));
+ EXPECT_EQ(false, minijail_unsetenv(env, nullptr));
+ EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
+ dump_env(env));
+ EXPECT_EQ(false, minijail_unsetenv(nullptr, nullptr));
+ EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
+ dump_env(env));
+ EXPECT_EQ(false, minijail_unsetenv(nullptr, "nonexisting"));
+ EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
+ dump_env(env));
+ EXPECT_EQ(false, minijail_unsetenv(env, "val1="));
+ EXPECT_EQ("val1=3\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\nnew2=8\n",
+ dump_env(env));
+ EXPECT_EQ(true, minijail_unsetenv(env, "val1"));
+ EXPECT_EQ("new2=8\nval2=4\ndup=5\ndup=2\nempty=\nnew1=7\n", dump_env(env));
+ EXPECT_EQ(true, minijail_unsetenv(env, "empty"));
+ EXPECT_EQ("new2=8\nval2=4\ndup=5\ndup=2\nnew1=7\n", dump_env(env));
+ EXPECT_EQ(true, minijail_unsetenv(env, "new2"));
+ EXPECT_EQ("new1=7\nval2=4\ndup=5\ndup=2\n", dump_env(env));
+ EXPECT_EQ(true, minijail_unsetenv(env, "new1"));
+ EXPECT_EQ("dup=2\nval2=4\ndup=5\n", dump_env(env));
+
minijail_free_env(env);
}