NetBSD Problem Report #59836
From www@netbsd.org Sun Dec 14 20:20:22 2025
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (2048 bits)
client-signature RSA-PSS (2048 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 49B701A9239
for <gnats-bugs@gnats.NetBSD.org>; Sun, 14 Dec 2025 20:20:22 +0000 (UTC)
Message-Id: <20251214202020.D326E1A923A@mollari.NetBSD.org>
Date: Sun, 14 Dec 2025 20:20:20 +0000 (UTC)
From: hpaluch@seznam.cz
Reply-To: hpaluch@seznam.cz
To: gnats-bugs@NetBSD.org
Subject: 11.0_BETA: resolvconf fails with 'eval: make_vars: IP_OF_2ND_DNS: not found' for more than 1 dns server
X-Send-Pr-Version: www-1.0
>Number: 59836
>Category: bin
>Synopsis: 11.0_BETA: resolvconf fails with 'eval: make_vars: IP_OF_2ND_DNS: not found' for more than 1 dns server
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Dec 14 20:25:00 +0000 2025
>Closed-Date: Sun Dec 28 09:25:27 +0000 2025
>Last-Modified: Sun Dec 28 09:25:27 +0000 2025
>Originator: Henryk Paluch
>Release: NetBSD 11.0_BETA (GENERIC) #0: Fri Dec 12 19:34:43 UTC 2025
>Organization:
N/A
>Environment:
NetBSD nbsd-x2 11.0_BETA NetBSD 11.0_BETA (GENERIC) #0: Fri Dec 12 19:34:43 UTC 2025 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
When resolvconf is run and you have more than 1 DNS server of same class (IPv4 or IPv6) from DHCP server, it will just throws error:
nbsd-x2# /sbin/resolvconf -u
eval: make_vars: 78.157.167.57: not found
eval: make_vars: 2a02:d8a0:2::: not found
and generates empty /etc/resolv.conf (no DNS servers defined)
It is because it improperly adds single quotes around each item of NAMESERVERS variables that later cause eval issue.
Warning: This error occurs only if there is more than one nameserver in specific class (at least 2 IPv4 nameservers or at least 2 IPv6 nameservers returned by DHCP server).
>How-To-Repeat:
You need to have DHCP server that returns at least 2 IPv4 DNS servers or at least 2 IPV6 DNS servers and then:
Run
/sbin/resolvconf -u
on latest NetBSD 11 Beta (tested 20251212193443Z) you will get errors:
eval: make_vars: 78.157.167.57: not found
eval: make_vars: 2a02:d8a0:2::: not found
Where 78.157.167.57 is my 2nd IPv4 DNS server (1st is OK) and 2a02:d8a0:2::: is my 2nd IPv6 DNS.
After this error - generated /etc/resolv.conf is empty:
# Generated by resolvconf
While using fixed resolvconf or older NetBSD 10.1 - generated /etc/resolv.conf contains all DNS servers (in my case 2 IPv4 and 2 IPv6):
# Generated by resolvconf
nameserver 78.157.167.7
nameserver 78.157.167.57
nameserver 2a02:d8a0:1::
nameserver 2a02:d8a0:2::
>Fix:
I use following patch (inspired by NetBSD 10.1 resolvconf that works properly) to fix it:
--- sbin/resolvconf.orig 2025-12-14 11:14:03.422798639 +0100
+++ sbin/resolvconf 2025-12-14 21:00:51.731497397 +0100
@@ -31,7 +31,7 @@ LIBEXECDIR=/libexec/resolvconf
VARDIR=/var/run/resolvconf
RCDIR=/etc/rc.d
RESTARTCMD=
-
+#set -x
if [ "$1" = "--version" ]; then
echo "openresolv $OPENRESOLV_VERSION"
echo "Copyright (c) 2007-2025 Roy Marples"
@@ -334,7 +334,8 @@ parse_resolv()
printf '%s\n' "SEARCH=\"\$SEARCH \"$search"
fi
if ! $private; then
- printf '%s\n' "NAMESERVERS=\"\$NAMESERVERS \"$ns"
+ ns=$( echo "$ns" | tr -d "'" )
+ echo "NAMESERVERS=\"\$NAMESERVERS $ns\""
fi
ns=
search=
>Release-Note:
>Audit-Trail:
From: Henryk Paluch <hpaluch@seznam.cz>
To: gnats-bugs@netbsd.org
Cc: roy <roy@NetBSD.org>
Subject: Re: bin/59836: 11.0_BETA: resolvconf fails with 'eval: make_vars:
IP_OF_2ND_DNS: not found' for more than 1 dns server
Date: Mon, 15 Dec 2025 07:35:19 +0100
Looks like there is fresh related commit:
> Revision 1.13.2.2: download - view: text, markup, annotated - select for diffs
> Sun Dec 14 11:35:59 2025 UTC (18 hours, 39 minutes ago) by martin
> Branches: netbsd-11
> Diff to: previous 1.13.2.1: preferred, colored; branchpoint 1.13: preferred, colored; next MAIN 1.14: preferred, colored
> Changes since revision 1.13.2.1: +13 -12 lines
>
> Pull up following revision(s) (requested by roy in ticket #122):
>
> external/bsd/openresolv/dist/resolvconf.in: revision 1.17
>
> resolvconf: quote on printf rather than on value
>
Source:
https://cvsweb.netbsd.org/bsdweb.cgi/src/external/bsd/openresolv/dist/resolvconf.in.diff?r1=1.13.2.1;r2=1.13.2.2;f=h
Bug URL: https://gnats.netbsd.org/59836
On 12/14/25 21:25, gnats-admin@netbsd.org wrote:
> Thank you very much for your problem report.
> It has the internal identification `bin/59836'.
> The individual assigned to look at your
> report is: bin-bug-people.
>
>> Category: bin
>> Responsible: bin-bug-people
>> Synopsis: 11.0_BETA: resolvconf fails with 'eval: make_vars: IP_OF_2ND_DNS: not found' for more than 1 dns server
>> Arrival-Date: Sun Dec 14 20:25:00 +0000 2025
>
From: Roy Marples <roy@marples.name>
To: <hpaluch@seznam.cz>
Cc: <gnats-bugs@netbsd.org>, <roy@NetBSD.org>
Subject: Re: bin/59836: 11.0_BETA: resolvconf fails with 'eval: make_vars:
IP_OF_2ND_DNS: not found' for more than 1 dns server
Date: Mon, 15 Dec 2025 07:23:37 +0000
------=_Part_2300933_766973908.1765783417224
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
And does that commit now fix it for you?
Roy
---- On Mon, 15 Dec 2025 06:35:19 +0000 Henryk Paluch <hpaluch@seznam.cz> w=
rote ----
Looks like there is fresh related commit:=20
=20
=20
> Revision 1.13.2.2: download - view: text, markup, annotated - select for =
diffs=20
> Sun Dec 14 11:35:59 2025 UTC (18 hours, 39 minutes ago) by martin=20
> Branches: netbsd-11=20
> Diff to: previous 1.13.2.1: preferred, colored; branchpoint 1.13: preferr=
ed, colored; next MAIN 1.14: preferred, colored=20
> Changes since revision 1.13.2.1: +13 -12 lines=20
>=20
> Pull up following revision(s) (requested by roy in ticket #122):=20
>=20
> =C2=A0=C2=A0=C2=A0=C2=A0external/bsd/openresolv/dist/resolvconf.in: revis=
ion 1.17=20
>=20
> resolvconf: quote on printf rather than on value=20
>=20
=20
=20
Source:=20
https://cvsweb.netbsd.org/bsdweb.cgi/src/external/bsd/openresolv/dist/resol=
vconf.in.diff?r1=3D1.13.2.1;r2=3D1.13.2.2;f=3Dh =20
=20
Bug URL: https://gnats.netbsd.org/59836 =20
=20
On 12/14/25 21:25, mailto:gnats-admin@netbsd.org wrote:=20
> Thank you very much for your problem report.=20
> It has the internal identification `bin/59836'.=20
> The individual assigned to look at your=20
> report is: bin-bug-people.=20
>=20
>> Category: bin=20
>> Responsible: bin-bug-people=20
>> Synopsis: 11.0_BETA: resolvconf fails with 'eval: make_vars: IP_OF=
_2ND_DNS: not found' for more than 1 dns server=20
>> Arrival-Date: Sun Dec 14 20:25:00 +0000 2025=20
>
------=_Part_2300933_766973908.1765783417224
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head>=
<meta content=3D"text/html;charset=3DUTF-8" http-equiv=3D"Content-Type"></h=
ead><body ><div style=3D"font-family: Verdana; font-size: 11pt;"><div dir=
=3D"ltr" style=3D"text-align: left;">And does that commit now fix it for yo=
u?</div><div><br></div><div id=3D"signatureElementId"><div>Roy</div></div><=
div><br></div><div data-zbluepencil-ignore=3D"true"><div><br><br></div><div=
class=3D"replyHeader">---- On Mon, 15 Dec 2025 06:35:19 +0000 Henryk Pa=
luch <hpaluch@seznam.cz> wrote ----<br></div><div><br></div><bloc=
kquote style=3D"margin:0 0 0 0"><div>Looks like there is fresh related comm=
it: <br> <br> <br>> Revision 1.13.2.2: download - view: text, markup, an=
notated - select for diffs <br>> Sun Dec 14 11:35:59 2025 UTC (18 hours,=
39 minutes ago) by martin <br>> Branches: netbsd-11 <br>> Diff to: p=
revious 1.13.2.1: preferred, colored; branchpoint 1.13: preferred, colored;=
next MAIN 1.14: preferred, colored <br>> Changes since revision 1.13.2.=
1: +13 -12 lines <br>> <br>> Pull up following revision(s) (requested=
by roy in ticket #122): <br>> <br>> external=
/bsd/openresolv/dist/resolvconf.in: revision 1.17 <br>> <br>> resolvc=
onf: quote on printf rather than on value <br>> <br> <br> <br>Source: <b=
r><a href=3D"https://cvsweb.netbsd.org/bsdweb.cgi/src/external/bsd/openreso=
lv/dist/resolvconf.in.diff?r1=3D1.13.2.1;r2=3D1.13.2.2;f=3Dh" target=3D"_bl=
ank">https://cvsweb.netbsd.org/bsdweb.cgi/src/external/bsd/openresolv/dist/=
resolvconf.in.diff?r1=3D1.13.2.1;r2=3D1.13.2.2;f=3Dh</a> <br> <br>Bug URL: =
<a href=3D"https://gnats.netbsd.org/59836" target=3D"_blank">https://gnats.=
netbsd.org/59836</a> <br> <br>On 12/14/25 21:25, <a href=3D"mailto:gnats-ad=
min@netbsd.org" target=3D"_blank">gnats-admin@netbsd.org</a> wrote: <br>>=
; Thank you very much for your problem report. <br>> It has the internal=
identification `bin/59836'. <br>> The individual assigned to look at yo=
ur <br>> report is: bin-bug-people. <br>> <br>>> Category: =
bin <br>>> Responsible: bin-bug-people <br>>> Synopsis: =
11.0_BETA: resolvconf fails with 'eval: make_vars: IP_OF_2ND_DNS: not f=
ound' for more than 1 dns server <br>>> Arrival-Date: Sun Dec 14 20=
:25:00 +0000 2025 <br>> <br> <br></div></blockquote></div><div><br></div=
></div><br></body></html>
------=_Part_2300933_766973908.1765783417224--
From: Henryk Paluch <hpaluch@seznam.cz>
To: gnats-bugs@netbsd.org
Cc: roy@NetBSD.org
Subject: Re: bin/59836: 11.0_BETA: resolvconf fails with 'eval: make_vars:
IP_OF_2ND_DNS: not found' for more than 1 dns server
Date: Mon, 15 Dec 2025 09:50:22 +0100
On 12/15/25 08:23, Roy Marples wrote:
> And does that commit now fix it for you?
>
>
> Roy
Yes, it works, but it introduced new potential security bug, because it
now passes untrusted user data ($NAMESERVERS) as format string to
printf(1) - which is generally dangerous, because attacker could add
something like '%s' (or any other '%' argument) changing printf(1)
behavior in unexpected way. What I mean:
From:
https://github.com/NetBSD/src/commit/025246054c2b2ce5d47c2d8943b71d93a4a0fb19
Original line used printf properly (format string is constant and
defined by script - no external user data involved):
printf '%s\n' "NAMESERVERS=\"\$NAMESERVERS \"$ns"
But fixed lines passes (untrusted) user data as format string which
opens potential to attacks (user can pass '%something' changing behavior
of printf(1) command):
printf 'NAMESERVERS="$NAMESERVERS "%s\n' "$(quote "$ns")"
As general recommendation - 1st argument of printf(1) - format string
should never contain external (untrusted) data to avoid unexpected behavior.
From: Robert Elz <kre@munnari.OZ.AU>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: bin/59836: 11.0_BETA: resolvconf fails with 'eval: make_vars: IP_OF_2ND_DNS: not found' for more than 1 dns server
Date: Tue, 16 Dec 2025 03:48:16 +0700
Date: Mon, 15 Dec 2025 09:00:03 +0000 (UTC)
From: "Henryk Paluch via gnats" <gnats-admin@NetBSD.org>
Message-ID: <20251215090003.629BA1A923A@mollari.NetBSD.org>
| but it introduced new potential security bug, because it
| now passes untrusted user data ($NAMESERVERS) as format string to
| printf(1)
No, it doesn't:
| printf 'NAMESERVERS="$NAMESERVERS "%s\n' "$(quote "$ns")"
Look more carefully, it passes the characters:
NAMESERVERS= (that part is obvious)
"
$
NAMESERVERS
space
"
%s
\n
All enclosed in ' ' (no interpretation of what's in the string,
other than what printf does - the %s gets the parameter's value,
and the \n turns into a newline).
The result should look something like (on stdout)
NAMESERVERS="$NAMESERVERS "'1.2.3.4'
(and what is in $NAMESERVERS when the shell which processes that
gets to see it will be all quoted strings, where the quotes will
then be removed by doing an "eval"). The 1.2.3.4 is untrusted
user data, but that's nicely hidden inside '' quotes. It might not
be useful as a nameserver, but it isn't going to do any harm.
kre
From: Henryk Paluch <hpaluch@seznam.cz>
To: gnats-bugs@netbsd.org
Cc: kre@munnari.OZ.AU
Subject: Re: bin/59836: 11.0_BETA: resolvconf fails with 'eval: make_vars:
IP_OF_2ND_DNS: not found' for more than 1 dns server
Date: Tue, 16 Dec 2025 07:01:32 +0100
Still, it is bad security practice to pass variable(s) in format string.
Any future change in variable processing may trigger unexpected change
in printf output behavior. Proper way would be something like:
# TODO: properly quote $NAMESERVER content to avoid '"' escape in eval,
etc.:
printf 'NAMESERVERS="%s" %s\n' "$(some_quote $NAMESERVERS)" "$(quote "$ns")"
To be sure that printf format string is always valid and references
exactly 2 arguments no matter what content of arguments is.
Or using echo which is immune to such things as long as start of 1st
argument does not contain '-' which is no problem in our case where
string starts with literal.
Additionally running whole output of make_vars using eval as root is
security nightmare on its own - because if any part of make_vars output
does not properly sanitize all content it may lead to root execution
exploit in future.
Just this bug (not security one) demonstrated that eval problem pretty
well - when single quote in wrong place caused shell execution errors...
However I'm not responsible for NetBSD security so I that's all I have
to say on this topic.
On 12/15/25 21:50, Robert Elz via gnats wrote:
> The following reply was made to PR bin/59836; it has been noted by GNATS.
>
> From: Robert Elz <kre@munnari.OZ.AU>
> To: gnats-bugs@netbsd.org
> Cc:
> Subject: Re: bin/59836: 11.0_BETA: resolvconf fails with 'eval: make_vars: IP_OF_2ND_DNS: not found' for more than 1 dns server
> Date: Tue, 16 Dec 2025 03:48:16 +0700
>
> Date: Mon, 15 Dec 2025 09:00:03 +0000 (UTC)
> From: "Henryk Paluch via gnats" <gnats-admin@NetBSD.org>
> Message-ID: <20251215090003.629BA1A923A@mollari.NetBSD.org>
>
> | but it introduced new potential security bug, because it
> | now passes untrusted user data ($NAMESERVERS) as format string to
> | printf(1)
>
> No, it doesn't:
>
> | printf 'NAMESERVERS="$NAMESERVERS "%s\n' "$(quote "$ns")"
>
> Look more carefully, it passes the characters:
>
> NAMESERVERS= (that part is obvious)
> "
> $
> NAMESERVERS
> space
> "
> %s
> \n
>
> All enclosed in ' ' (no interpretation of what's in the string,
> other than what printf does - the %s gets the parameter's value,
> and the \n turns into a newline).
>
> The result should look something like (on stdout)
>
> NAMESERVERS="$NAMESERVERS "'1.2.3.4'
>
> (and what is in $NAMESERVERS when the shell which processes that
> gets to see it will be all quoted strings, where the quotes will
> then be removed by doing an "eval"). The 1.2.3.4 is untrusted
> user data, but that's nicely hidden inside '' quotes. It might not
> be useful as a nameserver, but it isn't going to do any harm.
>
> kre
From: Robert Elz <kre@munnari.OZ.AU>
To: Henryk Paluch <hpaluch@seznam.cz>
Cc: gnats-bugs@netbsd.org
Subject: Re: bin/59836: 11.0_BETA: resolvconf fails with 'eval: make_vars: IP_OF_2ND_DNS: not found' for more than 1 dns server
Date: Wed, 17 Dec 2025 07:32:46 +0700
Date: Tue, 16 Dec 2025 07:01:32 +0100
From: Henryk Paluch <hpaluch@seznam.cz>
Message-ID: <37b539e1-f624-4b10-9a90-c55181758b3f@seznam.cz>
| Still, it is bad security practice to pass variable(s) in format string.
Variables that contain unknown data, yes, it is.
But you still seem to be missing the point. That is not what was
happening here, the format string contained (contains) no variables
at all.
Consider this example
printf '$(cat /dev/tty)\n'
What that writes out is (literally)
$(cat /dev/tty)
(including a newline of course). There is no command substitution, no
commands run, no reference to any device, just a string of characters
written to standard output.
That the string happens to look like a command substitution (in this
case) or a variable reference (in the resolvconf case) makes no
difference to anything, it is just a string of characters.
Once again, in sh, NOTHING inside a single quoted string is interpreted
by the shell in any way at all. That includes dollar signs, double quotes,
backslashes, grave accents (backticks), braces, ... the only character the
shell looks for in a single quoted string is the next single quote, which
ends the thing. And that is what the format string given used, just like
the example above.
The format string for printf should usually (when it needs any quoting)
be quoted using single quotes -- except in the very rare case when var
references ae actually needed there - which, if you want to be portable,
can be needed if, for example, the script wants to calculate field
widths, you might have a loop calculating the width needed something
like:
W=0
for X
do
if [ "${#X}" -gt "$W" ]
then
W=${#X}
fi
done
W=$(( W + 1 )) # One more than the longest
for X
do
printf "%-${W}s [other stuff]\n" "$X" [other args]
done
In our printf (and many others) you might instead do
printf '%-*s [other stuff]\n' "$W" "$X" [other args]
but support for '*' as the field width (or precision), isn't required
by POSIX, precisely because the version with the embedded $W reference
is possible (and perfectly safe - we know what kind of data must be in $W,
it has to be a number, and nothing else.)
| # TODO: properly quote $NAMESERVER content to avoid '"' escape in eval,
| etc.:
| printf 'NAMESERVERS="%s" %s\n' "$(some_quote $NAMESERVERS)" "$(quote "$ns")"
No it wouldn't, that's using the value of $NAMESERVERS (and quoting it
however the fictional some_quote function does it, which is irrelevant
here) which the original does not do. It didn't, even in its earlier
incarnations. The *only* variable expansion is of $ns. The one in
resolvconf writes the characters dollar, N, A, M, E, S, E, ... where
you think it is writing the value of a variable. I thought that was
clear from my previous reply.
| Or using echo which is immune to such things
echo is close to useless in portable programs. There are versions
of it which treat \ in the string (anywhere, the only way to prevent it
is to use \\, and if we're assuming user data, we cannot assume that)
to cause strange variations, and since this output is to be interpreted
by a shell later, as commands (I presume), allowing a \n to get in there
possibly followed by "rm -fr / &" and another newline after that, would
be nasty indeed. echo is never better than printf (just sometimes it
is quicker to type, echo is a shorter word than printf, and doesn't need
a format string arg, so lazy script writers tend to use it (and of
course it was around for many years before printf was, but by comparison
with how long printf has been available now, that's almost irrelevant.)
Original Bell labs echo doesn't do that, and BSD echo doesn't do that,
but Sys V (and POSIX) versions of echo do - even though these days POSIX
says that if the string starts with a '-' or contains a \ then the
results are unspecified (which is no help to us, or anyone, at all.)
| Additionally running whole output of make_vars using eval as root is
| security nightmare on its own - because if any part of make_vars output
| does not properly sanitize all content it may lead to root execution
| exploit in future.
This one I can't comment on, as I have no idea what the relevance is
to the issue, nor what might be doing something like that, nor why.
kre
From: Henryk Paluch <hpaluch@seznam.cz>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: bin/59836: 11.0_BETA: resolvconf fails with 'eval: make_vars:
IP_OF_2ND_DNS: not found' for more than 1 dns server
Date: Thu, 18 Dec 2025 13:26:13 +0100
And here it comes...
===
https://www.freebsd.org/security/advisories/FreeBSD-SA-25:12.rtsold.asc
resolvconf(8) is a shell script which does not validate its input. A
lack of
quoting meant that shell commands pass as input to resolvconf(8) may be
executed.
===
So my complains on resolvconf(8) security are not as baseless as many
people wish...
On 12/17/25 01:32, Robert Elz wrote:
> Date: Tue, 16 Dec 2025 07:01:32 +0100
> From: Henryk Paluch <hpaluch@seznam.cz>
> Message-ID: <37b539e1-f624-4b10-9a90-c55181758b3f@seznam.cz>
>
> | Still, it is bad security practice to pass variable(s) in format string.
>
> Variables that contain unknown data, yes, it is.
>
> But you still seem to be missing the point. That is not what was
> happening here, the format string contained (contains) no variables
> at all.
>
> Consider this example
>
> printf '$(cat /dev/tty)\n'
>
> What that writes out is (literally)
>
> $(cat /dev/tty)
>
> (including a newline of course). There is no command substitution, no
> commands run, no reference to any device, just a string of characters
> written to standard output.
>
> That the string happens to look like a command substitution (in this
> case) or a variable reference (in the resolvconf case) makes no
> difference to anything, it is just a string of characters.
>
> Once again, in sh, NOTHING inside a single quoted string is interpreted
> by the shell in any way at all. That includes dollar signs, double quotes,
> backslashes, grave accents (backticks), braces, ... the only character the
> shell looks for in a single quoted string is the next single quote, which
> ends the thing. And that is what the format string given used, just like
> the example above.
>
> The format string for printf should usually (when it needs any quoting)
> be quoted using single quotes -- except in the very rare case when var
> references ae actually needed there - which, if you want to be portable,
> can be needed if, for example, the script wants to calculate field
> widths, you might have a loop calculating the width needed something
> like:
>
> W=0
> for X
> do
> if [ "${#X}" -gt "$W" ]
> then
> W=${#X}
> fi
> done
> W=$(( W + 1 )) # One more than the longest
>
> for X
> do
> printf "%-${W}s [other stuff]\n" "$X" [other args]
> done
>
> In our printf (and many others) you might instead do
>
> printf '%-*s [other stuff]\n' "$W" "$X" [other args]
>
> but support for '*' as the field width (or precision), isn't required
> by POSIX, precisely because the version with the embedded $W reference
> is possible (and perfectly safe - we know what kind of data must be in $W,
> it has to be a number, and nothing else.)
>
>
>
> | # TODO: properly quote $NAMESERVER content to avoid '"' escape in eval,
> | etc.:
> | printf 'NAMESERVERS="%s" %s\n' "$(some_quote $NAMESERVERS)" "$(quote "$ns")"
>
> No it wouldn't, that's using the value of $NAMESERVERS (and quoting it
> however the fictional some_quote function does it, which is irrelevant
> here) which the original does not do. It didn't, even in its earlier
> incarnations. The *only* variable expansion is of $ns. The one in
> resolvconf writes the characters dollar, N, A, M, E, S, E, ... where
> you think it is writing the value of a variable. I thought that was
> clear from my previous reply.
>
> | Or using echo which is immune to such things
>
> echo is close to useless in portable programs. There are versions
> of it which treat \ in the string (anywhere, the only way to prevent it
> is to use \\, and if we're assuming user data, we cannot assume that)
> to cause strange variations, and since this output is to be interpreted
> by a shell later, as commands (I presume), allowing a \n to get in there
> possibly followed by "rm -fr / &" and another newline after that, would
> be nasty indeed. echo is never better than printf (just sometimes it
> is quicker to type, echo is a shorter word than printf, and doesn't need
> a format string arg, so lazy script writers tend to use it (and of
> course it was around for many years before printf was, but by comparison
> with how long printf has been available now, that's almost irrelevant.)
>
> Original Bell labs echo doesn't do that, and BSD echo doesn't do that,
> but Sys V (and POSIX) versions of echo do - even though these days POSIX
> says that if the string starts with a '-' or contains a \ then the
> results are unspecified (which is no help to us, or anyone, at all.)
>
> | Additionally running whole output of make_vars using eval as root is
> | security nightmare on its own - because if any part of make_vars output
> | does not properly sanitize all content it may lead to root execution
> | exploit in future.
>
> This one I can't comment on, as I have no idea what the relevance is
> to the issue, nor what might be doing something like that, nor why.
>
> kre
>
From: Roy Marples <roy@marples.name>
To: "Henryk Paluch" <hpaluch@seznam.cz>
Cc: "gnats-bugs" <gnats-bugs@netbsd.org>, "roy" <roy@NetBSD.org>
Subject: Re: bin/59836: 11.0_BETA: resolvconf fails with 'eval: make_vars:
IP_OF_2ND_DNS: not found' for more than 1 dns server
Date: Thu, 25 Dec 2025 15:34:00 +0000
---- On Thu, 18 Dec 2025 13:26:13 +0100 Henryk Paluch <hpaluch@seznam.cz> wrote ---
> And here it comes...
>
> ===
> https://www.freebsd.org/security/advisories/FreeBSD-SA-25:12.rtsold.asc
>
> resolvconf(8) is a shell script which does not validate its input. A
> lack of
> quoting meant that shell commands pass as input to resolvconf(8) may be
> executed.
> ===
> So my complains on resolvconf(8) security are not as baseless as many
> people wish...
I don't think anyone said they were baseless. And the FreeBSD sec team notified me of this issue some time ago, hence this new release to solve the problem.
The root cause is in FreeBSD rtsold as it's not validating it's input.
resolvconf works by parsing a resolv.conf(5) file fed in per key and we make no claims as to what constitutes a valid entry because every libc resolver is different and supports different options.
nameserver should be a valid IPv4 or IPv6 address.
The domain or search entries *should* contain alphanumberics only as per RFC1053 (allowing for - in the middle) and each label *should* be at most 63 characters, you get the idea.
IPv8 might come along and use the $ or ` symbol in the address makeup for example - resolvconf should still work.
The local libc might work with punycode natively allowing non alphanumerics in the search, which again would break resolvconf validation.
resolvconf doest not know this and shouldn't have to know this - it just edits /etc/resolv.conf and configures nameservers from it's input which should already be sanitized by the higher level protocols which know how their
protocol demands it's delivered.
No, this is purely a quoting issue for resolvconf. The design is basically process each resolv.conf file in order and extract key/values from it, process and output the final variables.
Because the input is fed in via a pipe into a while .. read ... done loop we have to eval the variables back in as a pipe cannot changes variables in the main process.
For NetBSD at least this is a none issue as dhcpcd ensures that this attack cannot happen because the DHCP/DHCPv6/RA RFC's mandate DNS restrictions so that these special shell escape characters don't even hit resolvconf.
Something that should be fixed? Sure.
Remote exploit? Not for NetBSD.
Roy
From: Henryk Paluch <hpaluch@seznam.cz>
To: gnats-bugs@netbsd.org, roy <roy@NetBSD.org>
Cc:
Subject: Re: bin/59836: 11.0_BETA: resolvconf fails with 'eval: make_vars:
IP_OF_2ND_DNS: not found' for more than 1 dns server
Date: Sat, 27 Dec 2025 16:57:33 +0100
Anyway - original reported problem (resolvconf crashing on eval leaving
empty /etc/resolv.conf) seems to be fixed by Revision 1.13.2.2 for
netbsd-11 branch.
Feel free to close this PR.
On 12/25/25 16:35, Roy Marples via gnats wrote:
...
>
> I don't think anyone said they were baseless. And the FreeBSD sec team notified me of this issue some time ago, hence this new release to solve the problem.
> The root cause is in FreeBSD rtsold as it's not validating it's input.
>
> resolvconf works by parsing a resolv.conf(5) file fed in per key and we make no claims as to what constitutes a valid entry because every libc resolver is different and supports different options.
> nameserver should be a valid IPv4 or IPv6 address.
> The domain or search entries *should* contain alphanumberics only as per RFC1053 (allowing for - in the middle) and each label *should* be at most 63 characters, you get the idea.
>
> IPv8 might come along and use the $ or ` symbol in the address makeup for example - resolvconf should still work.
> The local libc might work with punycode natively allowing non alphanumerics in the search, which again would break resolvconf validation.
> resolvconf doest not know this and shouldn't have to know this - it just edits /etc/resolv.conf and configures nameservers from it's input which should already be sanitized by the higher level protocols which know how their
> protocol demands it's delivered.
>
> No, this is purely a quoting issue for resolvconf. The design is basically process each resolv.conf file in order and extract key/values from it, process and output the final variables.
> Because the input is fed in via a pipe into a while .. read ... done loop we have to eval the variables back in as a pipe cannot changes variables in the main process.
>
> For NetBSD at least this is a none issue as dhcpcd ensures that this attack cannot happen because the DHCP/DHCPv6/RA RFC's mandate DNS restrictions so that these special shell escape characters don't even hit resolvconf.
> Something that should be fixed? Sure.
> Remote exploit? Not for NetBSD.
>
> Roy
>
State-Changed-From-To: open->closed
State-Changed-By: roy@NetBSD.org
State-Changed-When: Sun, 28 Dec 2025 09:25:27 +0000
State-Changed-Why:
Confirmed fixed
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.