Re: [Dnsmasq-discuss] [PATCH] Heap use after free in dhcp6_no_relay (CVE-2022-0934)

2022-03-31 Thread Simon Kelley

On 31/03/2022 20:04, Petr Menšík wrote:
Possible vulnerability were found in latest dnsmasq. It were found with 
help of oss-fuzz Google project by me and short after that independently 
also by Richard Johnson of Trellix Threat Labs.


It is affected only by DHCPv6 requests, which could be crafted to modify 
already freed memory. Red Hat security assigned this vulnerability 
CVE-2022-0934. Affected are also previous versions including 2.85, 2.79 
and 2.76. Correction is relative simple, I am attaching my proposal to 
fix this issue. Simon will probably use his own commit in upcoming 
version to fix this issue soon in git repository. We think it might be 
triggered remotely, but we do not think it could be used to execute 
remote code.


Best Regards,

Petr Menšík

--
Petr Menšík
Software Engineer
Red Hat,http://www.redhat.com/
email:pemen...@redhat.com
PGP: DFCF908DB7C87E8E529925BC4931CA5B6C9FC5CB



I just pushed my fix at

https://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=03345ecefeb0d82e3c3a4c28f27c3554f0611b39

It attempts a clean-up of the code. Petr's patch is a better base for a 
minimally-invasive backport fix.


Cheers,

Simon.

___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss


Re: [Dnsmasq-discuss] editing resolv.conf blocks dnsmasq, but not right away

2022-03-31 Thread Edward McGuire
> From: Geert Stappers
> Sent: Thursday, March 31, 2022 06:31

> From: Simon Kelley 
> Sent: Thursday, March 31, 2022 08:53

As I feared, I made a clueless error. I created a syslog deadlock.
This is the very case for which the perfectly well documented option
"log-async" exists, and that solved the problem.

Thank you both for responding! Once I ruled out the possibilities
you had me look into, it became easier to see where I actually
erred.

The only part I still don't understand is the 10 to 20 minute delay.

Geert> Most likely due cache content considered valid.

If it were DNS caching in dnsmasq, then when I restart with
cache-size=0, maybe that should eliminate the delay -- instead I
should see the problem instantly. But the behavior stayed the same.
I read syslogd.c, and found no cache code there. The docs on
getnameinfo() claim it does not cache unless you spin up ncsd.

That's where I stopped for now. There's no practical reason now for
me to look any further, just that I don't like mysteries. If time
permits I'll turn on debugging in sysklogd and dnsmasq, and share
what I find.

Cheers
Edward

___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss


[Dnsmasq-discuss] [PATCH] Heap use after free in dhcp6_no_relay (CVE-2022-0934)

2022-03-31 Thread Petr Menšík
Possible vulnerability were found in latest dnsmasq. It were found with
help of oss-fuzz Google project by me and short after that independently
also by Richard Johnson of Trellix Threat Labs.

It is affected only by DHCPv6 requests, which could be crafted to modify
already freed memory. Red Hat security assigned this vulnerability
CVE-2022-0934. Affected are also previous versions including 2.85, 2.79
and 2.76. Correction is relative simple, I am attaching my proposal to
fix this issue. Simon will probably use his own commit in upcoming
version to fix this issue soon in git repository. We think it might be
triggered remotely, but we do not think it could be used to execute
remote code.

Best Regards,

Petr Menšík

-- 
Petr Menšík
Software Engineer
Red Hat, http://www.redhat.com/
email: pemen...@redhat.com
PGP: DFCF908DB7C87E8E529925BC4931CA5B6C9FC5CB
From dcc62a514092c8afeab4e502db9e65f03c2e1d47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= 
Date: Tue, 22 Feb 2022 00:45:01 +0100
Subject: [PATCH] Change message type by dedicated function

Long-term pointer to beginning of message does not work well. I case
outpacket is reallocated in any new_opt6() section, original outmsgtypep
pointer becomes invalid. Instead of using that pointer use dedicated
function, which will change just the first byte of the message.

This makes sure correct beginning of packet is always used.
---
 src/dnsmasq.h   |  1 +
 src/outpacket.c | 11 +++
 src/rfc3315.c   | 29 ++---
 3 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 51a1aa6..c1c75c1 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1736,6 +1736,7 @@ void put_opt6_long(unsigned int val);
 void put_opt6_short(unsigned int val);
 void put_opt6_char(unsigned int val);
 void put_opt6_string(char *s);
+void put_msgtype6(unsigned int val);
 #endif
 
 /* radv.c */
diff --git a/src/outpacket.c b/src/outpacket.c
index abb3a3a..f322811 100644
--- a/src/outpacket.c
+++ b/src/outpacket.c
@@ -115,4 +115,15 @@ void put_opt6_string(char *s)
   put_opt6(s, strlen(s));
 }
 
+void put_msgtype6(unsigned int val)
+{
+  if (outpacket_counter == 0)
+put_opt6_char(val);
+  else
+{
+  unsigned char *p = daemon->outpacket.iov_base;
+  *p = val;
+}
+}
+
 #endif
diff --git a/src/rfc3315.c b/src/rfc3315.c
index cee8382..baeb51e 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -110,7 +110,6 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
   void *end = inbuff + sz;
   void *opts = inbuff + 34;
   int msg_type = *((unsigned char *)inbuff);
-  unsigned char *outmsgtypep;
   void *opt;
   struct dhcp_vendor *vendor;
 
@@ -192,9 +191,9 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
 return 0;
   
   /* copy header stuff into reply message and set type to reply */
-  if (!(outmsgtypep = put_opt6(inbuff, 34)))
+  if (!put_opt6(inbuff, 34))
 return 0;
-  *outmsgtypep = DHCP6RELAYREPL;
+  put_msgtype6(DHCP6RELAYREPL);
 
   /* look for relay options and set tags if found. */
   for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
@@ -267,7 +266,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
   struct dhcp_netid *tagif;
   struct dhcp_config *config = NULL;
   struct dhcp_netid known_id, iface_id, v6_id;
-  unsigned char *outmsgtypep;
+  unsigned char *xid;
   struct dhcp_vendor *vendor;
   struct dhcp_context *context_tmp;
   struct dhcp_mac *mac_opt;
@@ -297,10 +296,10 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
   state->tags = &v6_id;
 
   /* copy over transaction-id, and save pointer to message type */
-  if (!(outmsgtypep = put_opt6(inbuff, 4)))
+  if (!(xid = put_opt6(inbuff, 4)))
 return 0;
   start_opts = save_counter(-1);
-  state->xid = outmsgtypep[3] | outmsgtypep[2] << 8 | outmsgtypep[1] << 16;
+  state->xid = xid[3] | xid[2] << 8 | xid[1] << 16;

   /* We're going to be linking tags from all context we use. 
  mark them as unused so we don't link one twice and break the list */
@@ -347,7 +346,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
   (msg_type == DHCP6REQUEST || msg_type == DHCP6RENEW || msg_type == DHCP6RELEASE || msg_type == DHCP6DECLINE))
 
 {  
-  *outmsgtypep = DHCP6REPLY;
+  put_msgtype6(DHCP6REPLY);
   o1 = new_opt6(OPTION6_STATUS_CODE);
   put_opt6_short(DHCP6USEMULTI);
   put_opt6_string("Use multicast");
@@ -619,11 +618,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
 	struct dhcp_netid *solicit_tags;
 	struct dhcp_context *c;
 	
-	*outmsgtypep = DHCP6ADVERTISE;
+	put_msgtype6(DHCP6ADVERTISE);
 	
 	if (opt6_find(state->packet_options, state->end, OPTION6_RAPID_COMMIT, 0))
 	  {
-	*outmsgtypep = DHCP6REPLY;
+	put_msgtype6(DHCP6REPLY);
 	state->lease_allocate = 1;
 	   

Re: [Dnsmasq-discuss] Feature request = block-conf

2022-03-31 Thread Ercolino de Spiacico
My understanding is that the script-conf feature was to be used to 
reduce filesystem storage usage, ie instead of a conf-file full of lines 
like


address=/domain1.com/
address=/domain2.com/

Juts the list of domains could be stored, in compressed form, and then 
they would be decompressed and decorated with the address=/./ stuff 
on the fly before being fed into the dnsmasq configuration parser.


The  scripts you posted earlier seemed to

1) Download the block list.
2) compress it
3) feed it to dnsmasq which decompresses it

Which is the worst of all possible worlds, since it uses more storage 
for the compressed AND uncompressed versions, and more CPU to the 
compression and decompression. It also make the down-time depend on how 
fast the block list downloads.



OK, but as you rightly pointed out a couple of messages ago, all these 
operations are performed before the service dnsmasq restart.


Because of this I have performed an additional test to complete the 
picture:


my usual 650K list of domains is now unzipped and I have simply scripted 
the usual formatting with address=/domain/. So no compression involved 
this time. e.g.


/bin/cat /mnt/USB/adblock/adblock.domains | /bin/sed -e "s:^:address=/:" 
-e "s:$:/:"



The service dnsmasq restart went from 15.something sec of the script+zip 
version to 14.4 sec of this script only version.

root@sparrow:/tmp/mnt/USB/adblock# time service dnsmasq restart

Done.
real0m 14.43s
user0m 0.00s
sys 0m 0.00s

What I was trying to say is that feeding pre-formatted config (as per 
prev message posted here) takes 4.2 sec on the very same file.


And you're right the aim here is to minimize storage hence RAM demand, 
but the dnsmasq restart time must also stay within acceptable levels as 
nobody wants the DNS resolution to be down for too long.


So to summarize: Because the conf-script option works great on RAM 
reduction but takes a big hit on the restart time, I was suggesting if a 
different approach could/should be considered. Since we learnt from this 
last test that the zip operation add only 1-2 sec of delay on the restart


root@sparrow:/mnt/USB/adblock# time gzip -d adblock.domains.unloaded.gz
real0m 1.76s
user0m 0.67s
sys 0m 0.18s

perhaps allowing the conf-file to process zipped content (internal zcat 
or something) would suffice to achieve the desired result to minimize 
storage demand and retain restart time within acceptable levels. 
Allowing something like conf-block and import domain only is indeed 
nice-to-have but secondary in my opinion compared to support for 
compressed config:


root@sparrow:/mnt/USB/adblock# ls -lh adblock.domains.unloaded
-rwxrwxrwx1 root root   14.3M Mar 31 18:42
root@sparrow:/mnt/USB/adblock# gzip adblock.domains.unloaded
root@sparrow:/mnt/USB/adblock# ls -lh adblock.domains.unloaded.gz
-rwxrwxrwx1 root root4.2M Mar 31 18:42


My 2 cents

___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss


Re: [Dnsmasq-discuss] Feature request = block-conf

2022-03-31 Thread Simon Kelley




On 30/03/2022 12:13, Ercolino de Spiacico wrote:
It looks like your script which downloads the blocked domains file and 
compresses it takes 15s, then dnsmasq takes 15s to uncompress the list 
and load it into memory and sort.


The first delay can be solved by doing the download before stopping 
the old dnsmasq process. The second is amenable the new option to 
SIGTERM the old dnsmasq _after_ parsing the new config.


I run some additional test to verify the impact. I got the very same 
list (650K records) unzipped and pre-formatted (address=/$domain/) to be 
used by the standard conf-file directive. As we used to do before the 
conf-script was introduced. Here the result:


root@sparrow:/tmp/mnt/USB/adblock# time service dnsmasq restart
..
Done.
real    0m 4.21s
user    0m 0.00s
sys 0m 0.01s

The amazing part is that there's no measurable delay in the change of 
ownership from root to nobody. So 4.2 seconds and that's it which is 
completely acceptable for this list size. But then we're back to square 
1 before this conversation ever happened. So I'm starting to conclude 
that the scripting part (script-conf) and it's interpretation 
internally, despite being flexible in terms of wanted output, it doesn't 
scale well on large block-files. Fair enough admittedly this has never 
been the reason why dnsmasq was originally created.


This also make me think further about two (potentially even overlapping) 
ways to progress:


A- Going back to my original idea to have a new conf-block (or 
block-conf whichever) directive where any domain defined in the target 
file will be blocked (only domains without formatting) dnsmasq would do 
an internal interpretation of this list of domains based on the 
directive. So smaller list size and no extra processing needed. This 
perhaps could be an option to have the cake and eat it?


B- Allow the conf-block= and/or the existing conf-file= to read a zipped 
source e.g.

conf-block=z,/bla/bla/file.gz
conf-file=z,/bla/bla/file.gz
Again no scripting/manipulation but taking advantage of the on-the-fly 
decompression





My understanding is that the script-conf feature was to be used to 
reduce filesystem storage usage, ie instead of a conf-file full of lines 
like


address=/domain1.com/
address=/domain2.com/

Juts the list of domains could be stored, in compressed form, and then 
they would be decompressed and decorated with the address=/./ stuff 
on the fly before being fed into the dnsmasq configuration parser.


The  scripts you posted earlier seemed to

1) Download the block list.
2) compress it
3) feed it to dnsmasq which decompresses it

Which is the worst of all possible worlds, since it uses more storage 
for the compressed AND uncompressed versions, and more CPU to the 
compression and decompression. It also make the down-time depend on how 
fast the block list downloads.


Simon.


___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss


Re: [Dnsmasq-discuss] dnsmasq stable bug report

2022-03-31 Thread Simon Kelley




On 31/03/2022 01:00, dnsm...@riseup.net wrote:

The reason it's like this is that if dnsmasq changed to unprivileged
action would fail if the port number was less than 1024


Look at the bug report again - its port is above 1024.

Without 'query-port=' your software always open way too many ports
(above 1024), and those conections are always made by dnsmasq user.

With 'query-port' the UDP connection was made by only this port, but
those connections are NOT MADE by dnsmasq user.

How could this is NOT A BUG!?


The UID associated with a connection is not defined anywhere in the 
documentation. Indeed, as a concept it's pretty weak anyway: UID don't 
exist in IP headers, so I assume this is something that only applies to 
locally generated packets using iptables. Dnsmasq doesn't define the 
value of the UID associated with it's sockets, and it's not clear 
obvious what that that UID should be if it did, since it's meaningless, 
hence not a bug.


One could argue that for ports >1024, the socket opening should be 
delayed to after the dnsmasq UID is changed from root to the dnsmasq 
user. That would be a backwards compatible change, since no promises 
have been made about the UID on socket opening. Convince me that this is 
a useful change (It's non-trivial) and I'll consider it.




Using Debian's stable btw




you lose source-port randomisation,


There is a option and I am using it.


I suggest you research DNS source-port randomisation and the Kaminski 
attack. Then determine if the security you're losing by disabling source 
port randomisation is compensated for by your firewall rules.


Simon.


___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss



___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss


Re: [Dnsmasq-discuss] editing resolv.conf blocks dnsmasq, but not right away

2022-03-31 Thread Geert Stappers via Dnsmasq-discuss
On Wed, Mar 30, 2022 at 10:57:38PM +, Edward McGuire wrote:
> Dnsmasq 2.86
> Slackware Linux 15.0
> 
> This dnsmasq server provides DNS and DHCP service to a local network
> of about 150 devices. My problem emerges when I uncomment the first
> line of /etc/resolv.conf:
> 
> #nameserver 127.0.0.1
> nameserver [ISP ip redacted]
> nameserver [ISP ip redacted]
> 
> For 10 or 20 minutes after the edit,
> dnsmasq continues to operate perfectly.

Most likely due cache content considered valid.


> Then all client queries begin to time out.

Dnsmasq cache content expired.


> If I comment out the line again, the problem immediately disappears.
> 
> The problem is reliably reproducible. if I uncomment the line again,
> dnsmasq again operates perfectly for some time, then all client queries
> begin to time out again.
> 
> In /etc/dnsmasq.conf I have option "no-resolv" set. So it mystifies
> me that dnsmasq behavior would be affected by changes to resolv.conf.
> 
> Not seeing any error messages logged. What I do see is the rate of all
> activities logged slows to a crawl. I get about two messages per minute
> where the normal rate is hundreds per minute. Here's an example with
> "log-dhcp" turned on:
> 
> Mar 30 17:33:40 slack dnsmasq-dhcp[946]: 940533162 next server: [ip redacted]
> Mar 30 17:34:05 slack dnsmasq-dhcp[946]: 940533162 sent size:  1 option: 53 
> message-type  5
> Mar 30 17:34:40 slack dnsmasq-dhcp[946]: 940533162 sent size:  4 option: 54 
> server-identifier  [ip redacted]
> Mar 30 17:35:16 slack dnsmasq-dhcp[946]: 940533162 sent size:  4 option: 28 
> broadcast  [ip redacted]
> Mar 30 17:35:52 slack dnsmasq-dhcp[946]: 940533162 sent size:  4 option:  3 
> router  [ip redacted]
> Mar 30 17:36:22 slack dnsmasq-dhcp[946]: 940533162 sent size:  4 option:  1 
> netmask  [ip redacted]
> Mar 30 17:36:52 slack dnsmasq-dhcp[946]: 940533162 sent size: 12 option:  6 
> dns-server  [local ip redacted], [ISP ip redacted], [ISP ip redacted]
> 
> These log entries show a single DHCP response taking the daemon several
> MINUTES to complete! So something is blocking dnsmasq pretty badly.

s/something is blocking dnsmasq/something is blocking name resolving/

 
> This is my first attempt at a dnsmasq installation. So my fear is
> I've made a clueless error and just don't know enough to recognize
> it. Any ideas?

dig @[ISP ip redacted]  dnsmasq.org

 
> Cheers
> Edward


Groeten
Geert Stappers
-- 
Silence is hard to parse

___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss