minijail: Add support for dropping caps with static binaries
This change relaxes the preconditions needed for dropping caps, such
that it is supported provided that at least one of these two are true:
* The program being run is dynamically-linked, which means that the
LD_PRELOAD trick can be used to drop caps after execve().
* Ambient capabilities are also being set, which makes the capability
bound to be able to survive an execve().
Additionally, this change validates that the parameters passed into the
minijail0 binary comply with the preconditions, and suggest the
alternative of passing in --ambient to fix it.
Bug: 63069223
Test: $ g++ -static -std=c++11 -xc++ -o captest - << EOF
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ifstream status("/proc/self/status");
std::string line;
while (std::getline(status, line)) {
if (line.find("CapEff") == 0) {
std::cout << line << std::endl;
}
}
return 0;
}
EOF
$ sudo ./captest
CapEff: 0000003fffffffff
$ sudo ./minijail0 -T static -c 1fffffffff ./captest
Can't run statically-linked binaries with capabilities (-c) \
without also setting ambient capabilities. Try passing --ambient
$ sudo ./minijail0 -T static -c 1fffffffff --ambient ./captest
CapEff: 0000001fffffffff
Change-Id: Ie8be509303780a09356ce94bd1436a861a59ce80
diff --git a/libminijail.c b/libminijail.c
index b119542..6381c30 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -2011,9 +2011,11 @@
}
if (!use_preload) {
- if (j->flags.use_caps && j->caps != 0)
- die("non-empty capabilities are not supported without "
- "LD_PRELOAD");
+ if (j->flags.use_caps && j->caps != 0 &&
+ !j->flags.set_ambient_caps) {
+ die("non-empty, non-ambient capabilities are not "
+ "supported without LD_PRELOAD");
+ }
}
/*