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 &lt;hpaluch@seznam.cz&gt; 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>&gt; Revision 1.13.2.2: download - view: text, markup, an=
 notated - select for diffs <br>&gt; Sun Dec 14 11:35:59 2025 UTC (18 hours,=
  39 minutes ago) by martin <br>&gt; Branches: netbsd-11 <br>&gt; Diff to: p=
 revious 1.13.2.1: preferred, colored; branchpoint 1.13: preferred, colored;=
  next MAIN 1.14: preferred, colored <br>&gt; Changes since revision 1.13.2.=
 1: +13 -12 lines <br>&gt; <br>&gt; Pull up following revision(s) (requested=
  by roy in ticket #122): <br>&gt; <br>&gt; &nbsp;&nbsp;&nbsp;&nbsp;external=
 /bsd/openresolv/dist/resolvconf.in: revision 1.17 <br>&gt; <br>&gt; resolvc=
 onf: quote on printf rather than on value <br>&gt; <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>&gt=
 ; Thank you very much for your problem report. <br>&gt; It has the internal=
  identification `bin/59836'. <br>&gt; The individual assigned to look at yo=
 ur <br>&gt; report is: bin-bug-people. <br>&gt; <br>&gt;&gt; Category:     =
   bin <br>&gt;&gt; Responsible:    bin-bug-people <br>&gt;&gt; Synopsis:   =
     11.0_BETA: resolvconf fails with 'eval: make_vars: IP_OF_2ND_DNS: not f=
 ound' for more than 1 dns server <br>&gt;&gt; Arrival-Date:   Sun Dec 14 20=
 :25:00 +0000 2025 <br>&gt; <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:

NetBSD Home
NetBSD PR Database Search

(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.