Merge pull request #14512 from poettering/root-image-devices

Make RootImage= work reliable with DeviceAllow= in the mix
This commit is contained in:
Lennart Poettering 2020-01-08 12:18:38 +01:00 committed by GitHub
commit 48dfa8b0e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 12 deletions

View File

@ -720,10 +720,15 @@
<para>Note that whitelists defined this way should only reference device groups which are
resolvable at the time the unit is started. Any device groups not resolvable then are not added to
the device whitelist. In order to work around this limitation, consider extending service units
with an <command>ExecStartPre=/sbin/modprobe…</command> line that loads the necessary
kernel module implementing the device group if missing. Example: <programlisting>
with a pair of <command>After=modprobe@xyz.service</command> and
<command>Wants=modprobe@xyz.service</command> lines that load the necessary kernel module
implementing the device group if missing.
Example: <programlisting>
[Unit]
Wants=modprobe@loop.service
After=modprobe@loop.service
[Service]
ExecStartPre=-/sbin/modprobe -abq loop
DeviceAllow=block-loop
DeviceAllow=/dev/loop-control
</programlisting></para>

View File

@ -38,7 +38,13 @@ static int bpf_access_type(const char *acc) {
return r;
}
static int bpf_prog_whitelist_device(BPFProgram *prog, char type, int major, int minor, const char *acc) {
static int bpf_prog_whitelist_device(
BPFProgram *prog,
char type,
int major,
int minor,
const char *acc) {
int r, access;
assert(prog);
@ -74,7 +80,12 @@ static int bpf_prog_whitelist_device(BPFProgram *prog, char type, int major, int
return r;
}
static int bpf_prog_whitelist_major(BPFProgram *prog, char type, int major, const char *acc) {
static int bpf_prog_whitelist_major(
BPFProgram *prog,
char type,
int major,
const char *acc) {
int r, access;
assert(prog);
@ -109,7 +120,11 @@ static int bpf_prog_whitelist_major(BPFProgram *prog, char type, int major, cons
return r;
}
static int bpf_prog_whitelist_class(BPFProgram *prog, char type, const char *acc) {
static int bpf_prog_whitelist_class(
BPFProgram *prog,
char type,
const char *acc) {
int r, access;
assert(prog);
@ -143,7 +158,11 @@ static int bpf_prog_whitelist_class(BPFProgram *prog, char type, const char *acc
return r;
}
int bpf_devices_cgroup_init(BPFProgram **ret, CGroupDevicePolicy policy, bool whitelist) {
int bpf_devices_cgroup_init(
BPFProgram **ret,
CGroupDevicePolicy policy,
bool whitelist) {
const struct bpf_insn pre_insn[] = {
/* load device type to r2 */
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
@ -306,7 +325,14 @@ int bpf_devices_supported(void) {
return supported = 1;
}
static int whitelist_device_pattern(BPFProgram *prog, const char *path, char type, const unsigned *maj, const unsigned *min, const char *acc) {
static int whitelist_device_pattern(
BPFProgram *prog,
const char *path,
char type,
const unsigned *maj,
const unsigned *min,
const char *acc) {
assert(IN_SET(type, 'b', 'c'));
if (cg_all_unified() > 0) {
@ -343,7 +369,12 @@ static int whitelist_device_pattern(BPFProgram *prog, const char *path, char typ
}
}
int bpf_devices_whitelist_device(BPFProgram *prog, const char *path, const char *node, const char *acc) {
int bpf_devices_whitelist_device(
BPFProgram *prog,
const char *path,
const char *node,
const char *acc) {
mode_t mode;
dev_t rdev;
int r;
@ -377,7 +408,13 @@ int bpf_devices_whitelist_device(BPFProgram *prog, const char *path, const char
return whitelist_device_pattern(prog, path, S_ISCHR(mode) ? 'c' : 'b', &maj, &min, acc);
}
int bpf_devices_whitelist_major(BPFProgram *prog, const char *path, const char *name, char type, const char *acc) {
int bpf_devices_whitelist_major(
BPFProgram *prog,
const char *path,
const char *name,
char type,
const char *acc) {
unsigned maj;
int r;
@ -459,7 +496,10 @@ int bpf_devices_whitelist_major(BPFProgram *prog, const char *path, const char *
return 0;
}
int bpf_devices_whitelist_static(BPFProgram *prog, const char *path) {
int bpf_devices_whitelist_static(
BPFProgram *prog,
const char *path) {
static const char auto_devices[] =
"/dev/null\0" "rwm\0"
"/dev/zero\0" "rwm\0"

View File

@ -4324,6 +4324,11 @@ int unit_patch_contexts(Unit *u) {
r = cgroup_add_device_allow(cc, "block-blkext", "rwm");
if (r < 0)
return r;
/* Make sure "block-loop" can be resolved, i.e. make sure "loop" shows up in /proc/devices */
r = unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, "modprobe@loop.service", true, UNIT_DEPENDENCY_FILE);
if (r < 0)
return r;
}
}

View File

@ -8,8 +8,11 @@
# (at your option) any later version.
[Unit]
Description=Load kernel module %i
Description=Load Kernel Module %i
DefaultDependencies=no
Before=sysinit.target
Documentation=man:modprobe(8)
ConditionCapability=CAP_SYS_MODULE
[Service]
Type=oneshot