resolvconf: reject malformed stdin without changing link state
The resolvconf compatibility parser ignored errors from
nameserver, domain, and search lines. If one of those lines was
malformed, resolvectl could still send the partially parsed
configuration to resolved and overwrite the previous link state.
Reproducer:
IF=enp1s0
TMP="$(mktemp -d)"
ln -s "$(command -v resolvectl)" "$TMP/resolvconf"
sudo resolvectl dns "$IF" 1.1.1.1
sudo resolvectl domain "$IF" keep.example
resolvectl domain "$IF"
printf 'nameserver 1.1.1.1\nsearch "unterminated\n' |
sudo "$TMP/resolvconf" -a "$IF" || true
resolvectl domain "$IF"
Before:
The malformed search line was ignored and the previous domain
was cleared:
Link 2 (enp1s0): keep.example
Link 2 (enp1s0):
After:
The malformed input fails before updating resolved, so
keep.example remains configured.
Follow-up for: 097f130731
This commit is contained in:
@@ -454,6 +454,9 @@ CHANGES WITH 261:
|
||||
|
||||
Changes in systemd-resolved:
|
||||
|
||||
* The resolvconf compatibility mode now rejects malformed stdin input
|
||||
and leaves the existing per-link DNS configuration unchanged.
|
||||
|
||||
* systemd-resolved will now read additional DNS resource record
|
||||
definitions to resolve locally from JSON drop-in files in
|
||||
{/etc,/run,/usr/local/lib,/usr/lib}/systemd/resolve/static.d/. This
|
||||
|
||||
+2
-1
@@ -564,7 +564,8 @@
|
||||
DNS configuration data from its standard input. Relevant fields are <literal>nameserver</literal> and
|
||||
<literal>domain</literal>/<literal>search</literal>. This command is mostly identical to invoking
|
||||
<command>resolvectl</command> with a combination of <option>dns</option> and <option>domain</option>
|
||||
commands.</para>
|
||||
commands. If a relevant input line has invalid syntax, the command fails and leaves the existing
|
||||
per-interface configuration unchanged.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v239"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
@@ -116,7 +116,9 @@ static int parse_stdin(LookupType lookup_type) {
|
||||
|
||||
a = first_word(line, "nameserver");
|
||||
if (a) {
|
||||
(void) parse_nameserver(a);
|
||||
r = parse_nameserver(a);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse resolv.conf nameserver line: %m");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -124,7 +126,9 @@ static int parse_stdin(LookupType lookup_type) {
|
||||
if (!a)
|
||||
a = first_word(line, "search");
|
||||
if (a) {
|
||||
(void) parse_search_domain(a);
|
||||
r = parse_search_domain(a);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse resolv.conf domain/search line: %m");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -273,6 +273,9 @@ manual_testcase_01_resolvectl() {
|
||||
assert_in 'test-domain1.example.com' "$(resolvectl domain hoge)"
|
||||
assert_in 'test-domain2.example.com' "$(resolvectl domain hoge)"
|
||||
assert_in 'test-search-domain.example.com' "$(resolvectl domain hoge)"
|
||||
resolvectl domain hoge keep.example
|
||||
(! echo -e "nameserver 10.0.2.1\nsearch \"unterminated" | SYSTEMD_INVOKED_AS=resolvconf resolvectl -a hoge)
|
||||
assert_in 'keep.example' "$(resolvectl domain hoge)"
|
||||
|
||||
# Tests for 'resolvconf -x'
|
||||
echo nameserver 10.0.2.1 | SYSTEMD_INVOKED_AS=resolvconf resolvectl -x -a hoge
|
||||
|
||||
Reference in New Issue
Block a user