1
0
mirror of https://github.com/systemd/systemd synced 2026-04-11 17:44:58 +02:00

Compare commits

...

5 Commits

Author SHA1 Message Date
Yu Watanabe
80bfc3b901 network: ndisc: ignore route prefix to ::/0
Fixes #21912.
2021-12-28 21:00:49 +00:00
Luca Boccassi
69b5c7cf2a
Merge pull request #21925 from yuwata/unit-file-symlinked-drop-in-directory
unit-file: fix symlinked drop-in directory handling
2021-12-28 20:38:24 +00:00
Yu Watanabe
cf6562e456 test: add testcases of symlinked drop-in directories 2021-12-29 01:29:21 +09:00
Yu Watanabe
7f304b8561 unti-file: fix symlinked drop-in directory handling
This fixes a bug introduced by 95ef0eaf0d5cd43fcc8e9eb541f2c342f25f8f2f.

Fixes #21920.
2021-12-29 01:29:17 +09:00
Luca Boccassi
4b3ad81bfa core: do not touch /run/systemd/systemd-units-load from user session instances
Follow-up for: 15b9243c0d
Fixes: https://github.com/systemd/systemd/issues/21911
2021-12-28 22:07:02 +09:00
4 changed files with 90 additions and 26 deletions

View File

@ -236,6 +236,31 @@ bool lookup_paths_timestamp_hash_same(const LookupPaths *lp, uint64_t timestamp_
return updated == timestamp_hash; return updated == timestamp_hash;
} }
static int directory_name_is_valid(const char *name) {
const char *suffix;
/* Accept a directory whose name is a valid unit file name ending in .wants/, .requires/ or .d/ */
FOREACH_STRING(suffix, ".wants", ".requires", ".d") {
_cleanup_free_ char *chopped = NULL;
const char *e;
e = endswith(name, suffix);
if (!e)
continue;
chopped = strndup(name, e - name);
if (!chopped)
return log_oom();
if (unit_name_is_valid(chopped, UNIT_NAME_ANY) ||
unit_type_from_string(chopped) >= 0)
return true;
}
return false;
}
int unit_file_build_name_map( int unit_file_build_name_map(
const LookupPaths *lp, const LookupPaths *lp,
uint64_t *cache_timestamp_hash, uint64_t *cache_timestamp_hash,
@ -287,50 +312,61 @@ int unit_file_build_name_map(
FOREACH_DIRENT_ALL(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) { FOREACH_DIRENT_ALL(de, d, log_warning_errno(errno, "Failed to read \"%s\", ignoring: %m", *dir)) {
_unused_ _cleanup_free_ char *_filename_free = NULL; _unused_ _cleanup_free_ char *_filename_free = NULL;
_cleanup_free_ char *simplified = NULL; _cleanup_free_ char *simplified = NULL;
bool symlink_to_dir = false;
const char *dst = NULL; const char *dst = NULL;
char *filename; char *filename;
/* We only care about valid units and dirs with certain suffixes, let's ignore the /* We only care about valid units and dirs with certain suffixes, let's ignore the
* rest. */ * rest. */
if (IN_SET(de->d_type, DT_REG, DT_LNK)) { if (de->d_type == DT_REG) {
/* Accept a regular file whose name is a valid unit file name. */
if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY)) if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
continue; continue;
/* Accept a regular file or symlink whose name is a valid unit file name. */
} else if (de->d_type == DT_DIR) { } else if (de->d_type == DT_DIR) {
bool valid_dir_name = false;
const char *suffix;
/* Also accept a directory whose name is a valid unit file name ending in
* .wants/, .requires/ or .d/ */
if (!paths) /* Skip directories early unless path_cache is requested */ if (!paths) /* Skip directories early unless path_cache is requested */
continue; continue;
FOREACH_STRING(suffix, ".wants", ".requires", ".d") { r = directory_name_is_valid(de->d_name);
_cleanup_free_ char *chopped = NULL; if (r < 0)
const char *e; return r;
if (r == 0)
continue;
e = endswith(de->d_name, suffix); } else if (de->d_type == DT_LNK) {
if (!e)
/* Accept a symlink file whose name is a valid unit file name or
* ending in .wants/, .requires/ or .d/. */
if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY)) {
_cleanup_free_ char *target = NULL;
if (!paths) /* Skip symlink to a directory early unless path_cache is requested */
continue; continue;
chopped = strndup(de->d_name, e - de->d_name); r = directory_name_is_valid(de->d_name);
if (!chopped) if (r < 0)
return log_oom(); return r;
if (r == 0)
continue;
if (unit_name_is_valid(chopped, UNIT_NAME_ANY) || r = readlinkat_malloc(dirfd(d), de->d_name, &target);
unit_type_from_string(chopped) >= 0) { if (r < 0) {
valid_dir_name = true; log_warning_errno(r, "Failed to read symlink %s/%s, ignoring: %m",
break; *dir, de->d_name);
continue;
} }
r = is_dir(target, /* follow = */ true);
if (r <= 0)
continue;
symlink_to_dir = true;
} }
if (!valid_dir_name)
continue;
} else } else
continue; continue;
@ -347,9 +383,11 @@ int unit_file_build_name_map(
} else } else
_filename_free = filename; /* Make sure we free the filename. */ _filename_free = filename; /* Make sure we free the filename. */
if (!IN_SET(de->d_type, DT_REG, DT_LNK)) if (de->d_type == DT_DIR || (de->d_type == DT_LNK && symlink_to_dir))
continue; continue;
assert(IN_SET(de->d_type, DT_REG, DT_LNK));
/* search_path is ordered by priority (highest first). If the name is already mapped /* search_path is ordered by priority (highest first). If the name is already mapped
* to something (incl. itself), it means that we have already seen it, and we should * to something (incl. itself), it means that we have already seen it, and we should
* ignore it here. */ * ignore it here. */

View File

@ -1728,9 +1728,10 @@ static void manager_ready(Manager *m) {
manager_catchup(m); manager_catchup(m);
/* Create a file which will indicate when the manager started loading units the last time. */ /* Create a file which will indicate when the manager started loading units the last time. */
(void) touch_file("/run/systemd/systemd-units-load", false, if (MANAGER_IS_SYSTEM(m))
m->timestamps[MANAGER_TIMESTAMP_UNITS_LOAD].realtime ?: now(CLOCK_REALTIME), (void) touch_file("/run/systemd/systemd-units-load", false,
UID_INVALID, GID_INVALID, 0444); m->timestamps[MANAGER_TIMESTAMP_UNITS_LOAD].realtime ?: now(CLOCK_REALTIME),
UID_INVALID, GID_INVALID, 0444);
m->honor_device_enumeration = true; m->honor_device_enumeration = true;
} }

View File

@ -612,6 +612,11 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Failed to get route prefix length: %m"); return log_link_error_errno(link, r, "Failed to get route prefix length: %m");
if (in6_addr_is_null(&dst) && prefixlen == 0) {
log_link_debug(link, "Route prefix is ::/0, ignoring");
return 0;
}
if (in6_prefix_is_filtered(&dst, prefixlen, link->network->ndisc_allow_listed_route_prefix, link->network->ndisc_deny_listed_route_prefix)) { if (in6_prefix_is_filtered(&dst, prefixlen, link->network->ndisc_allow_listed_route_prefix, link->network->ndisc_deny_listed_route_prefix)) {
if (DEBUG_LOGGING) { if (DEBUG_LOGGING) {
_cleanup_free_ char *buf = NULL; _cleanup_free_ char *buf = NULL;

View File

@ -515,6 +515,25 @@ test_invalid_dropins () {
return 0 return 0
} }
test_symlink_dropin_directory () {
# For issue #21920.
echo "Testing symlink drop-in directory..."
create_services test15-a
rmdir /{etc,run,usr/lib}/systemd/system/test15-a.service.d
mkdir -p /tmp/testsuite-15-test15-a-dropin-directory
ln -s /tmp/testsuite-15-test15-a-dropin-directory /etc/systemd/system/test15-a.service.d
cat >/tmp/testsuite-15-test15-a-dropin-directory/override.conf <<EOF
[Unit]
Description=hogehoge
EOF
ln -s /tmp/testsuite-15-test15-a-dropin-directory-nonexistent /run/systemd/system/test15-a.service.d
touch /tmp/testsuite-15-test15-a-dropin-directory-regular
ln -s /tmp/testsuite-15-test15-a-dropin-directory-regular /usr/lib/systemd/system/test15-a.service.d
check_ok test15-a Description hogehoge
clear_services test15-a
}
test_basic_dropins test_basic_dropins
test_linked_units test_linked_units
test_template_alias test_template_alias
@ -523,5 +542,6 @@ test_template_dropins
test_alias_dropins test_alias_dropins
test_masked_dropins test_masked_dropins
test_invalid_dropins test_invalid_dropins
test_symlink_dropin_directory
touch /testok touch /testok