aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuis Hector Chavez <lhchavez@google.com>2017-07-11 20:13:59 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-07-11 20:13:59 +0000
commit20f15e9c71d6eab00357086850dceba56a8ae86f (patch)
treea05d6063daebfb6aefccd704faee7b32f011d879
parentab5309116f52311d444a0e4fe8ae030044cbb28d (diff)
parent4a01d5fd555e5cc09041bdee5ecd783bc66962c5 (diff)
downloadminijail-20f15e9c71d6eab00357086850dceba56a8ae86f.tar.gz
minijail: Allow skipping setting securebits when restricting caps am: ec0a2c1023
am: 4a01d5fd55 Change-Id: Ib611fb9072333fd36c82010c31b9b8dd4b05d9bc
-rw-r--r--libminijail.c9
-rw-r--r--libminijail.h2
-rw-r--r--minijail0.c20
-rw-r--r--system.c11
-rw-r--r--system.h2
5 files changed, 37 insertions, 7 deletions
diff --git a/libminijail.c b/libminijail.c
index 6381c30..4d61b0d 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -166,6 +166,7 @@ struct minijail {
size_t cgroup_count;
struct minijail_rlimit rlimits[MAX_RLIMITS];
size_t rlimit_count;
+ uint64_t securebits_skip_mask;
};
/*
@@ -434,6 +435,12 @@ void API minijail_new_session_keyring(struct minijail *j)
j->flags.new_session_keyring = 1;
}
+void API minijail_skip_setting_securebits(struct minijail *j,
+ uint64_t securebits_skip_mask)
+{
+ j->securebits_skip_mask = securebits_skip_mask;
+}
+
void API minijail_skip_remount_private(struct minijail *j)
{
j->flags.skip_remount_private = 1;
@@ -1726,7 +1733,7 @@ void API minijail_enter(const struct minijail *j)
if (prctl(PR_SET_KEEPCAPS, 1))
pdie("prctl(PR_SET_KEEPCAPS) failed");
- if (lock_securebits() < 0) {
+ if (lock_securebits(j->securebits_skip_mask) < 0) {
pdie("locking securebits failed");
}
}
diff --git a/libminijail.h b/libminijail.h
index bad8407..ff06348 100644
--- a/libminijail.h
+++ b/libminijail.h
@@ -64,6 +64,8 @@ void minijail_reset_signal_mask(struct minijail *j);
void minijail_namespace_vfs(struct minijail *j);
void minijail_namespace_enter_vfs(struct minijail *j, const char *ns_path);
void minijail_new_session_keyring(struct minijail *j);
+void minijail_skip_setting_securebits(struct minijail *j,
+ uint64_t securebits_skip_mask);
/*
* This option is *dangerous* as it negates most of the functionality of
diff --git a/minijail0.c b/minijail0.c
index fb98163..6cc5efa 100644
--- a/minijail0.c
+++ b/minijail0.c
@@ -48,6 +48,18 @@ static void set_group(struct minijail *j, const char *arg)
}
}
+static void skip_securebits(struct minijail *j, const char *arg)
+{
+ uint64_t securebits_skip_mask;
+ char *end = NULL;
+ securebits_skip_mask = strtoull(arg, &end, 16);
+ if (*end) {
+ fprintf(stderr, "Invalid securebit mask: '%s'\n", arg);
+ exit(1);
+ }
+ minijail_skip_setting_securebits(j, securebits_skip_mask);
+}
+
static void use_caps(struct minijail *j, const char *arg)
{
uint64_t caps;
@@ -137,6 +149,9 @@ static void usage(const char *progn)
" -a <table>: Use alternate syscall table <table>.\n"
" -b: Bind <src> to <dest> in chroot.\n"
" Multiple instances allowed.\n"
+ " -B <mask> Skip setting securebits in <mask> when restricting capabilities (-c).\n"
+ " By default, SECURE_NOROOT, SECURE_NO_SETUID_FIXUP, and \n"
+ " SECURE_KEEP_CAPS (together with their respective locks) are set.\n"
" -k: Mount <src> at <dest> in chroot.\n"
" <flags> and <data> can be specified as in mount(2).\n"
" Multiple instances allowed.\n"
@@ -229,7 +244,7 @@ static int parse_args(struct minijail *j, int argc, char *argv[],
const char *filter_path;
const char *optstring =
- "+u:g:sS:c:C:P:b:V:f:m::M::k:a:e::R:T:vrGhHinNplLt::IUKwyYz";
+ "+u:g:sS:c:C:P:b:B:V:f:m::M::k:a:e::R:T:vrGhHinNplLt::IUKwyYz";
int longoption_index = 0;
/* clang-format off */
const struct option long_options[] = {
@@ -288,6 +303,9 @@ static int parse_args(struct minijail *j, int argc, char *argv[],
add_binding(j, optarg);
binding = 1;
break;
+ case 'B':
+ skip_securebits(j, optarg);
+ break;
case 'c':
caps = 1;
use_caps(j, optarg);
diff --git a/system.c b/system.c
index 49f8915..9373e87 100644
--- a/system.c
+++ b/system.c
@@ -51,7 +51,7 @@
_Static_assert(SECURE_ALL_BITS == 0x55, "SECURE_ALL_BITS == 0x55.");
#endif
-int lock_securebits(void)
+int lock_securebits(uint64_t skip_mask)
{
/*
* Ambient capabilities can only be raised if they're already present
@@ -59,9 +59,12 @@ int lock_securebits(void)
* need to lock the NO_CAP_AMBIENT_RAISE securebit, since we are already
* configuring the permitted and inheritable set.
*/
- int securebits_ret =
- prctl(PR_SET_SECUREBITS,
- SECURE_BITS_NO_AMBIENT | SECURE_LOCKS_NO_AMBIENT);
+ uint64_t securebits =
+ (SECURE_BITS_NO_AMBIENT | SECURE_LOCKS_NO_AMBIENT) & ~skip_mask;
+ if (!securebits) {
+ return 0;
+ }
+ int securebits_ret = prctl(PR_SET_SECUREBITS, securebits);
if (securebits_ret < 0) {
pwarn("prctl(PR_SET_SECUREBITS) failed");
return -1;
diff --git a/system.h b/system.h
index 6f1be49..6b7da8b 100644
--- a/system.h
+++ b/system.h
@@ -48,7 +48,7 @@ extern "C" {
#define PR_CAP_AMBIENT_CLEAR_ALL 4
#endif
-int lock_securebits(void);
+int lock_securebits(uint64_t skip_mask);
unsigned int get_last_valid_cap(void);
int cap_ambient_supported(void);