test: cover DeviceAllow parsing

Add unit coverage for config_parse_device_allow().

Verify valid device paths and subsystem patterns, invalid
specifiers and rights, default permissions, and reset handling.

Follow-up for: 20d52ab60e
This commit is contained in:
dongshengyuan
2026-07-29 01:22:05 +09:00
committed by Yu Watanabe
parent 9b76949a47
commit 385623fee3
2 changed files with 66 additions and 3 deletions
-3
View File
@@ -2684,9 +2684,6 @@ SPDX-License-Identifier: LGPL-2.1-or-later
automatically support reverting back to older OS version images if newer ones
fail to boot.
- **test/:**
- add unit tests for config_parse_device_allow()
- The bind(AF_UNSPEC) construct (for resetting sockets to their initial state)
should be blocked in many cases because it punches holes in many sandboxes.
+66
View File
@@ -9,6 +9,7 @@
#include "all-units.h"
#include "alloc-util.h"
#include "capability-util.h"
#include "cgroup.h"
#include "conf-parser.h"
#include "fileio.h"
#include "format-util.h"
@@ -39,6 +40,15 @@ STATIC_DESTRUCTOR_REGISTER(runtime_dir, rm_rf_physical_and_freep);
/* For testing type compatibility. */
_unused_ static ConfigPerfItemLookup unused_lookup = load_fragment_gperf_lookup;
static size_t cgroup_device_allow_count(const CGroupContext *c) {
size_t n = 0;
LIST_FOREACH(device_allow, a, c->device_allow)
n++;
return n;
}
TEST_RET(unit_file_get_list) {
int r;
_cleanup_hashmap_free_ Hashmap *h = NULL;
@@ -878,6 +888,62 @@ TEST(config_parse_memory_limit) {
}
}
TEST(config_parse_device_allow) {
_cleanup_(cgroup_context_done) CGroupContext c = {};
_cleanup_(manager_freep) Manager *m = NULL;
_cleanup_(unit_freep) Unit *u = NULL;
CGroupDeviceAllow *a;
int r;
r = manager_new(RUNTIME_SCOPE_USER, MANAGER_TEST_RUN_MINIMAL, &m);
if (manager_errno_skip_test(r))
return (void) log_tests_skipped_errno(r, "manager_new() failed");
ASSERT_OK(r);
ASSERT_NOT_NULL(u = unit_new(m, sizeof(Service)));
ASSERT_OK_ZERO(unit_add_name(u, "null.service"));
ASSERT_OK_ZERO(config_parse_device_allow(u->id, "fake", 1, "Service", 1,
"DeviceAllow", 0, "/dev/%N rw",
&c, u));
ASSERT_EQ(cgroup_device_allow_count(&c), 1U);
ASSERT_NOT_NULL(a = c.device_allow);
ASSERT_STREQ(a->path, "/dev/null");
ASSERT_EQ(a->permissions, CGROUP_DEVICE_READ|CGROUP_DEVICE_WRITE);
ASSERT_OK_ZERO(config_parse_device_allow(u->id, "fake", 2, "Service", 1,
"DeviceAllow", 0, "char-pts rwm",
&c, u));
ASSERT_EQ(cgroup_device_allow_count(&c), 2U);
ASSERT_NOT_NULL(a = c.device_allow);
ASSERT_STREQ(a->path, "char-pts");
ASSERT_EQ(a->permissions, CGROUP_DEVICE_READ|CGROUP_DEVICE_WRITE|CGROUP_DEVICE_MKNOD);
ASSERT_OK_ZERO(config_parse_device_allow(u->id, "fake", 3, "Service", 1,
"DeviceAllow", 0, "%Q rw",
&c, u));
ASSERT_EQ(cgroup_device_allow_count(&c), 2U);
ASSERT_OK_ZERO(config_parse_device_allow(u->id, "fake", 4, "Service", 1,
"DeviceAllow", 0, "/dev/zero invalid",
&c, u));
ASSERT_EQ(cgroup_device_allow_count(&c), 2U);
ASSERT_OK_ZERO(config_parse_device_allow(u->id, "fake", 5, "Service", 1,
"DeviceAllow", 0, "/dev/zero",
&c, u));
ASSERT_EQ(cgroup_device_allow_count(&c), 3U);
ASSERT_NOT_NULL(a = c.device_allow);
ASSERT_STREQ(a->path, "/dev/zero");
ASSERT_EQ(a->permissions, _CGROUP_DEVICE_PERMISSIONS_ALL);
ASSERT_OK_ZERO(config_parse_device_allow(u->id, "fake", 6, "Service", 1,
"DeviceAllow", 0, "",
&c, u));
ASSERT_NULL(c.device_allow);
}
TEST(contains_instance_specifier_superset) {
ASSERT_TRUE(contains_instance_specifier_superset("foobar@a%i"));
ASSERT_TRUE(contains_instance_specifier_superset("foobar@%ia"));