conf: reject .conf files that declare duplicate block titles

The block title is the service identity, and libconfuse merges two
sections that share one, without a word.  Two blocks titled the same
in one file therefore loaded as a single service holding a mix of both
declarations, with scalars taken from the last block and lists reset
by it.

system/10-hotplug.conf.in is written this way: two udevd blocks, one
per candidate binary, the way the line-based format spelled a
fallback.  Only the second survived the merge, so a system that has
/lib/systemd/systemd-udevd but no udevd got no udevd service at all,
and the whole `if = "udevd"` chain behind it went with it.

CFGF_NO_TITLE_DUPES turns the merge into a parse error naming the file
and the title, and the file is then rejected as a whole.  The same
title in another file is untouched, that is how an administrator
overrides a system .conf.

Format detection had to stop agreeing with it.  is_new_format() probes
by parsing, so a duplicate title made it answer "not block format" and
conf_parse_file() handed the file to the legacy parser, whose errors
buried the real message.  The probe now clears the flag on its own
copy of the option array, keeping the verdict syntactic.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2026-08-05 17:56:40 +02:00
1 parent c3c41f113e
commit 516ee41494
3 files changed
+115 -5

No files matched your search

+2
View File
@@ -32,6 +32,7 @@ EXTRA_DIST += add-remove-dynamic-service-sub-config.sh
EXTRA_DIST += bootstrap-crash.sh
EXTRA_DIST += cond-start-task.sh
EXTRA_DIST += conf-format.sh
EXTRA_DIST += conf-dup-title.sh
EXTRA_DIST += conf-dirs.sh
EXTRA_DIST += conf-if.sh
EXTRA_DIST += conf-template.sh
@@ -81,6 +82,7 @@ TESTS += add-remove-dynamic-service-sub-config.sh
TESTS += bootstrap-crash.sh
TESTS += cond-start-task.sh
TESTS += conf-format.sh
TESTS += conf-dup-title.sh
TESTS += conf-dirs.sh
TESTS += conf-if.sh
TESTS += conf-template.sh