Merge pull request #29745 from mrc0mmand/more-tests
test: cover more sd-executor related stuff
This commit is contained in:
+20
-9
@@ -698,16 +698,14 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||||
prefix, bpf_cgroup_attach_type_to_string(p->attach_type), p->bpffs_path);
|
||||
|
||||
if (c->socket_bind_allow) {
|
||||
fprintf(f, "%sSocketBindAllow:", prefix);
|
||||
LIST_FOREACH(socket_bind_items, bi, c->socket_bind_allow)
|
||||
cgroup_context_dump_socket_bind_item(bi, f);
|
||||
fprintf(f, "%sSocketBindAllow: ", prefix);
|
||||
cgroup_context_dump_socket_bind_items(c->socket_bind_allow, f);
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
if (c->socket_bind_deny) {
|
||||
fprintf(f, "%sSocketBindDeny:", prefix);
|
||||
LIST_FOREACH(socket_bind_items, bi, c->socket_bind_deny)
|
||||
cgroup_context_dump_socket_bind_item(bi, f);
|
||||
fprintf(f, "%sSocketBindDeny: ", prefix);
|
||||
cgroup_context_dump_socket_bind_items(c->socket_bind_deny, f);
|
||||
fputc('\n', f);
|
||||
}
|
||||
|
||||
@@ -734,16 +732,29 @@ void cgroup_context_dump_socket_bind_item(const CGroupSocketBindItem *item, FILE
|
||||
}
|
||||
|
||||
if (item->nr_ports == 0)
|
||||
fprintf(f, " %s%s%s%sany", family, colon1, protocol, colon2);
|
||||
fprintf(f, "%s%s%s%sany", family, colon1, protocol, colon2);
|
||||
else if (item->nr_ports == 1)
|
||||
fprintf(f, " %s%s%s%s%" PRIu16, family, colon1, protocol, colon2, item->port_min);
|
||||
fprintf(f, "%s%s%s%s%" PRIu16, family, colon1, protocol, colon2, item->port_min);
|
||||
else {
|
||||
uint16_t port_max = item->port_min + item->nr_ports - 1;
|
||||
fprintf(f, " %s%s%s%s%" PRIu16 "-%" PRIu16, family, colon1, protocol, colon2,
|
||||
fprintf(f, "%s%s%s%s%" PRIu16 "-%" PRIu16, family, colon1, protocol, colon2,
|
||||
item->port_min, port_max);
|
||||
}
|
||||
}
|
||||
|
||||
void cgroup_context_dump_socket_bind_items(const CGroupSocketBindItem *items, FILE *f) {
|
||||
bool first = true;
|
||||
|
||||
LIST_FOREACH(socket_bind_items, bi, items) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
fputc(' ', f);
|
||||
|
||||
cgroup_context_dump_socket_bind_item(bi, f);
|
||||
}
|
||||
}
|
||||
|
||||
int cgroup_context_add_device_allow(CGroupContext *c, const char *dev, CGroupDevicePermissions p) {
|
||||
_cleanup_free_ CGroupDeviceAllow *a = NULL;
|
||||
_cleanup_free_ char *d = NULL;
|
||||
|
||||
@@ -273,6 +273,7 @@ void cgroup_context_init(CGroupContext *c);
|
||||
void cgroup_context_done(CGroupContext *c);
|
||||
void cgroup_context_dump(Unit *u, FILE* f, const char *prefix);
|
||||
void cgroup_context_dump_socket_bind_item(const CGroupSocketBindItem *item, FILE *f);
|
||||
void cgroup_context_dump_socket_bind_items(const CGroupSocketBindItem *items, FILE *f);
|
||||
|
||||
void cgroup_context_free_device_allow(CGroupContext *c, CGroupDeviceAllow *a);
|
||||
void cgroup_context_free_io_device_weight(CGroupContext *c, CGroupIODeviceWeight *w);
|
||||
|
||||
@@ -2968,9 +2968,9 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) {
|
||||
return r;
|
||||
c->ioprio_set = true;
|
||||
} else if ((val = startswith(l, "exec-context-cpu-scheduling-policy="))) {
|
||||
r = sched_policy_from_string(val);
|
||||
if (r < 0)
|
||||
return r;
|
||||
c->cpu_sched_policy = sched_policy_from_string(val);
|
||||
if (c->cpu_sched_policy < 0)
|
||||
return -EINVAL;
|
||||
c->cpu_sched_set = true;
|
||||
} else if ((val = startswith(l, "exec-context-cpu-scheduling-priority="))) {
|
||||
r = safe_atoi(val, &c->cpu_sched_priority);
|
||||
|
||||
@@ -49,9 +49,8 @@ static int test_socket_bind(
|
||||
return log_unit_error_errno(u, r, "Failed to parse SocketBindAllow: %m");
|
||||
}
|
||||
|
||||
fprintf(stderr, "SocketBindAllow:");
|
||||
LIST_FOREACH(socket_bind_items, bi, cc->socket_bind_allow)
|
||||
cgroup_context_dump_socket_bind_item(bi, stderr);
|
||||
fprintf(stderr, "SocketBindAllow: ");
|
||||
cgroup_context_dump_socket_bind_items(cc->socket_bind_allow, stderr);
|
||||
fputc('\n', stderr);
|
||||
|
||||
STRV_FOREACH(rule, deny_rules) {
|
||||
@@ -62,9 +61,8 @@ static int test_socket_bind(
|
||||
return log_unit_error_errno(u, r, "Failed to parse SocketBindDeny: %m");
|
||||
}
|
||||
|
||||
fprintf(stderr, "SocketBindDeny:");
|
||||
LIST_FOREACH(socket_bind_items, bi, cc->socket_bind_deny)
|
||||
cgroup_context_dump_socket_bind_item(bi, stderr);
|
||||
fprintf(stderr, "SocketBindDeny: ");
|
||||
cgroup_context_dump_socket_bind_items(cc->socket_bind_deny, stderr);
|
||||
fputc('\n', stderr);
|
||||
|
||||
exec_start = strjoin("-timeout --preserve-status -sSIGTERM 1s ", netcat_path, " -l ", port, " -vv");
|
||||
|
||||
@@ -74,6 +74,109 @@ if ! systemd-detect-virt -cq; then
|
||||
bash -xec "test ! -r /dev/kmsg"
|
||||
systemd-run --wait --pipe -p ProtectKernelLogs=no -p User=testuser \
|
||||
bash -xec "test -r /dev/kmsg"
|
||||
|
||||
# Check if we correctly serialize, deserialize, and set directives that
|
||||
# have more complex internal handling
|
||||
#
|
||||
# Funny detail: this originally used the underlying rootfs device, but that,
|
||||
# for some reason, caused "divide error" in kernel, followed by a kernel panic
|
||||
TEMPFILE="$(mktemp)"
|
||||
LODEV="$(losetup --show -f "$TEMPFILE")"
|
||||
ROOT_DEV_MAJ_MIN="$(lsblk -nro MAJ:MIN "$LODEV")"
|
||||
EXPECTED_IO_MAX="$ROOT_DEV_MAJ_MIN rbps=1000 wbps=1000000000000 riops=2000000000 wiops=4000"
|
||||
EXPECTED_IO_LATENCY="$ROOT_DEV_MAJ_MIN target=69000"
|
||||
SERVICE_NAME="test-io-directives-$RANDOM.service"
|
||||
CGROUP_PATH="/sys/fs/cgroup/system.slice/$SERVICE_NAME"
|
||||
|
||||
# IO*=
|
||||
ARGUMENTS=(
|
||||
# Throw in a couple of invalid entries just to test things out
|
||||
-p IOReadBandwidthMax="/foo/bar 1M"
|
||||
-p IOReadBandwidthMax="/foo/baz 1M"
|
||||
-p IOReadBandwidthMax="$LODEV 1M"
|
||||
-p IOReadBandwidthMax="$LODEV 1K"
|
||||
-p IOWriteBandwidthMax="$LODEV 1G"
|
||||
-p IOWriteBandwidthMax="$LODEV 1T"
|
||||
-p IOReadIOPSMax="$LODEV 2G"
|
||||
-p IOWriteIOPSMax="$LODEV 4K"
|
||||
-p IODeviceLatencyTargetSec="$LODEV 666ms"
|
||||
-p IODeviceLatencyTargetSec="/foo/bar 69ms"
|
||||
-p IODeviceLatencyTargetSec="$LODEV 69ms"
|
||||
-p IOReadBandwidthMax="/foo/bar 1M"
|
||||
-p IOReadBandwidthMax="/foo/baz 1M"
|
||||
# TODO: IODeviceWeight= doesn't work on loop devices and virtual disks
|
||||
-p IODeviceWeight="$LODEV 999"
|
||||
-p IODeviceWeight="/foo/bar 999"
|
||||
)
|
||||
|
||||
systemd-run --wait --pipe --unit "$SERVICE_NAME" "${ARGUMENTS[@]}" \
|
||||
bash -xec "diff <(echo $EXPECTED_IO_MAX) $CGROUP_PATH/io.max; diff <(echo $EXPECTED_IO_LATENCY) $CGROUP_PATH/io.latency"
|
||||
|
||||
# CPUScheduling=
|
||||
ARGUMENTS=(
|
||||
-p CPUSchedulingPolicy=rr # ID: 2
|
||||
-p CPUSchedulingPolicy=fifo # ID: 1
|
||||
-p CPUSchedulingPriority=5 # Actual prio: 94 (99 - prio)
|
||||
-p CPUSchedulingPriority=10 # Actual prio: 89 (99 - prio)
|
||||
)
|
||||
|
||||
systemd-run --wait --pipe --unit "$SERVICE_NAME" "${ARGUMENTS[@]}" \
|
||||
bash -xec 'grep -E "^policy\s*:\s*1$" /proc/self/sched; grep -E "^prio\s*:\s*89$" /proc/self/sched'
|
||||
|
||||
# Device*=
|
||||
ARGUMENTS=(
|
||||
-p DevicePolicy=closed
|
||||
-p DevicePolicy=strict
|
||||
-p DeviceAllow="char-mem rm" # Allow read & mknod for /dev/{null,zero,...}
|
||||
-p DeviceAllow="/dev/loop0 rw"
|
||||
-p DeviceAllow="/dev/loop0 w" # Allow write for /dev/loop0
|
||||
# Everything else should be disallowed per the strict policy
|
||||
)
|
||||
|
||||
systemd-run --wait --pipe --unit "$SERVICE_NAME" "${ARGUMENTS[@]}" \
|
||||
bash -xec 'test -r /dev/null; test ! -w /dev/null; test ! -r /dev/loop0; test -w /dev/loop0; test ! -r /dev/tty; test ! -w /dev/tty'
|
||||
|
||||
# SocketBind*=
|
||||
ARGUMENTS=(
|
||||
-p SocketBindAllow=
|
||||
-p SocketBindAllow=1234
|
||||
-p SocketBindAllow=ipv4:udp:any
|
||||
-p SocketBindAllow=ipv6:6666
|
||||
# Everything but the last assignment is superfluous, but it still excercises
|
||||
# the parsing machinery
|
||||
-p SocketBindDeny=
|
||||
-p SocketBindDeny=1111
|
||||
-p SocketBindDeny=ipv4:1111
|
||||
-p SocketBindDeny=ipv4:any
|
||||
-p SocketBindDeny=ipv4:tcp:any
|
||||
-p SocketBindDeny=ipv4:udp:10000-11000
|
||||
-p SocketBindDeny=ipv6:1111
|
||||
-p SocketBindDeny=any
|
||||
)
|
||||
|
||||
# We should fail with EPERM when trying to bind to a socket not on the allow list
|
||||
# (nc exits with 2 in that case)
|
||||
systemd-run --wait -p SuccessExitStatus="1 2" --pipe "${ARGUMENTS[@]}" \
|
||||
bash -xec 'timeout 1s nc -l 127.0.0.1 9999; exit 42'
|
||||
systemd-run --wait -p SuccessExitStatus="1 2" --pipe "${ARGUMENTS[@]}" \
|
||||
bash -xec 'timeout 1s nc -l ::1 9999; exit 42'
|
||||
systemd-run --wait -p SuccessExitStatus="1 2" --pipe "${ARGUMENTS[@]}" \
|
||||
bash -xec 'timeout 1s nc -6 -u -l ::1 9999; exit 42'
|
||||
systemd-run --wait -p SuccessExitStatus="1 2" --pipe "${ARGUMENTS[@]}" \
|
||||
bash -xec 'timeout 1s nc -4 -l 127.0.0.1 6666; exit 42'
|
||||
# Consequently, we should succeed when binding to a socket on the allow list
|
||||
# and keep listening on it until we're killed by `timeout` (EC 124)
|
||||
systemd-run --wait --pipe -p SuccessExitStatus=124 "${ARGUMENTS[@]}" \
|
||||
bash -xec 'timeout 1s nc -4 -l 127.0.0.1 1234; exit 1'
|
||||
systemd-run --wait --pipe -p SuccessExitStatus=124 "${ARGUMENTS[@]}" \
|
||||
bash -xec 'timeout 1s nc -4 -u -l 127.0.0.1 5678; exit 1'
|
||||
systemd-run --wait --pipe -p SuccessExitStatus=124 "${ARGUMENTS[@]}" \
|
||||
bash -xec 'timeout 1s nc -6 -l ::1 1234; exit 1'
|
||||
systemd-run --wait --pipe -p SuccessExitStatus=124 "${ARGUMENTS[@]}" \
|
||||
bash -xec 'timeout 1s nc -6 -l ::1 6666; exit 1'
|
||||
|
||||
losetup -d "$LODEV"
|
||||
rm -f "$TEMPFILE"
|
||||
fi
|
||||
|
||||
systemd-run --wait --pipe -p BindPaths="/etc /home:/mnt:norbind -/foo/bar/baz:/usr:rbind" \
|
||||
|
||||
Reference in New Issue
Block a user