Re: [Dnsmasq-discuss] [PATCH] Various fixes detected by static analysis

2018-08-21 Thread Simon Kelley
On 21/08/18 21:22, Petr Mensik wrote:
> Hi Simon and all others,
> 
> I have tried running dnsmasq under coverity, static analysis tool. It
> found some warnings. I have fixed some things. Most obvious error was
> inconsistent handling of buffer length of interface names. Buffer size
> is IFNAMSIZ long, that is 16 bytes. But if interface should have
> terminating zero, max. useable length is 15. Sometimes, buffer size is
> 16+1, sometimes only 16. Sometimes name might be sent to the kernel
> unterminated. According to [1] it cannot be longer in Linux.
> 
> I have created shared simple function that will always terminate string.
> And few little improvements around. What do you think?


Looks good on first look. I'll find time to go through it in more detail
and apply it soon.
> 
> It complains a lot about returns from one_opt in option.c. I can make
> patch that will deallocate memory before returning error. In some cases,
> i think option parsing does not have to be fatal. Would you accept fixes
> that will free memory before return? I think in some cases option
> parsing can be used for files that can be reread multiple times when
> running.

The only code where an error is not fatal is for dhcp-option, dhcp-host,
server and rev-server which get called when files containing just those
options are read dynamically. That means parse_dhcp_opt() and code
starting at 3025, 2401 and 2493
I suspect there are therefore memory leaks in those which might be worth
fixing. For the vast majority of errors in one_opt, they are fatal, and
complicating the code massively to avoid warnings from coverity is
probably not a good move.


Cheers,

Simon.



> 
> 1.
> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/diff/?id=f236da93df5be85409c24f03683e3d8c54fac72b
> 
> 
> 
> ___
> Dnsmasq-discuss mailing list
> Dnsmasq-discuss@lists.thekelleys.org.uk
> http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
> 


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


Re: [Dnsmasq-discuss] DNS query random ports

2018-08-21 Thread Simon Kelley
On 10/08/18 13:37, Petr Menšík wrote:
> Hello,
> 
> we discovered our dnsmasq  were using also privileged source ports when
> sending queries. Interesting enough, it has right to do it, because it
> has to listen also on privileged port. It never drops such privilege.
> 
> It was fixed in commit [1]. But my question is, why is there even custom
> generator or random ports, when OS can do it itself? And usually far
> better? So I dug a bit into it and came with patch, that would use
> random ports from OS by default.
> 
> When I tested it, I got the same results when skipping bind() call on
> random ports at all. Is there some reason, why dnsmasq does not follow
> OS policy for source outgoing port and choses its own range by itself?
> 
> 1.
> http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=baf553db0cdb50707ddab464fb3eff7786ea576c
> 

The random port code was added to dnsmasq in response to the Kaminsky
Birthday attack paper, which was in 2009. At that point, there were
still people seriously running routers (and therefore dnsmasq) on Linux
2.0 kernels. As best I remember, I did it the way I did because I
couldn't be sure that all the platforms dnsmasq would run on would
allocate sufficiently random ports: RFC6056 was still more than a year
in the future.


I'm sure that code could be simplified now.

Simon.


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


Re: [Dnsmasq-discuss] [PATCH] dhcpv6: fix unaligned access crash on aarch64

2018-08-21 Thread Simon Kelley
Thanks for chasing that down. Your patch will fix it, but I think it's
probably better to solve the problem at source, where we copy addresses
out of packets, rather than pass unaligned pointers to struct in6_addr
around and patch things up at the other end. That stops this coming and
biting us again.

That makes a much bigger patch, unfortunately.

I just pushed my attempt at doing that. Does it work OK for you?


Cheers,
Simon.

On 21/08/18 14:04, Vladislav Grishenko wrote:
> Hi, Simon
> 
>  
> 
> Faced with dnsmasq crash on aarch64 (32bit userspace,
> arm-buildroot-linux-gnueabi-gcc 5.3.0) with dhcpv6 stateful configured.
> 
> Unaligned packet’s req_addr is used in lease6_allocate() for struct copy
> since 2.67test15 (commit 89500e31f199e9ae1eadc86213b911ff44d30d6f).
> 
> As for other places, seems well-aligned stack-local vars are used.
> 
> Please refer proposed patch attached and gdb trace:
> 
>  
> 
> Program received signal SIGBUS, Bus error.
> 
> 0x0003f990 in lease6_allocate (addrp=0xa55e6, lease_type=32) at lease.c:822
> 
> 822       lease->addr6 = *addrp;
> 
> (gdb) bt
> 
> #0  0x0003f990 in lease6_allocate (addrp=0xa55e6, lease_type=32) at
> lease.c:822
> 
> #1  0x00055fac in update_leases (state=0xfffef8ac, context=0xa7ee8,
> addr=0xa55e6, lease_time=900, now=14609) at rfc3315.c:1825
> 
> #2  0x00055ab4 in add_address (state=0xfffef8ac, context=0xa7ee8,
> lease_time=900, ia_option=0xa55e2, min_time=0xfffef6d0, addr=0xa55e6,
> now=14609) at rfc3315.c:1684
> 
> #3  0x00053764 in dhcp6_no_relay (state=0xfffef8ac, msg_type=3,
> inbuff=0xa55a8, sz=128, is_unicast=0, now=14609) at rfc3315.c:938
> 
> #4  0x00051744 in dhcp6_maybe_relay (state=0xfffef8ac, inbuff=0xa55a8,
> sz=128, client_addr=0xfffef9a0, is_unicast=0, now=14609) at rfc3315.c:172
> 
> #5  0x000513b8 in dhcp6_reply (context=0xa7ee8, interface=23,
> iface_name=0xfffef978, fallback=0xfffef9f8, ll_addr=0xfffefa18,
> ula_addr=0xfffefa28, sz=128, client_addr=0xfffef9a0,
> 
>     now=14609) at rfc3315.c:103
> 
> #6  0x0004f4b4 in dhcp6_packet (now=14609) at dhcp6.c:233
> 
> #7  0x00038c78 in main (argc=3, argv=0xfffefd34) at dnsmasq.c:1099
> 
>  
> 
> Best Regards, Vladislav Grishenko
> 
>  
> 


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


[Dnsmasq-discuss] [PATCH] Various fixes detected by static analysis

2018-08-21 Thread Petr Mensik
Hi Simon and all others,

I have tried running dnsmasq under coverity, static analysis tool. It
found some warnings. I have fixed some things. Most obvious error was
inconsistent handling of buffer length of interface names. Buffer size
is IFNAMSIZ long, that is 16 bytes. But if interface should have
terminating zero, max. useable length is 15. Sometimes, buffer size is
16+1, sometimes only 16. Sometimes name might be sent to the kernel
unterminated. According to [1] it cannot be longer in Linux.

I have created shared simple function that will always terminate string.
And few little improvements around. What do you think?

It complains a lot about returns from one_opt in option.c. I can make
patch that will deallocate memory before returning error. In some cases,
i think option parsing does not have to be fatal. Would you accept fixes
that will free memory before return? I think in some cases option
parsing can be used for files that can be reread multiple times when
running.

1.
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/diff/?id=f236da93df5be85409c24f03683e3d8c54fac72b
-- 
Petr Menšík
Software Engineer
Red Hat, http://www.redhat.com/
email: pemen...@redhat.com  PGP: 65C6C973
From a6c3fe2f00468b7e135d5c51df1b8391c2f28733 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= 
Date: Wed, 15 Aug 2018 18:17:00 +0200
Subject: [PATCH 1/3] Fix lengths of interface names

Use helper function similar to copy correctly limited names into
buffers.
---
 src/bpf.c |  2 +-
 src/dhcp-common.c |  5 -
 src/dhcp.c|  9 -
 src/dnsmasq.h |  1 +
 src/log.c |  2 +-
 src/netlink.c |  5 +
 src/network.c | 12 ++--
 src/option.c  |  9 -
 src/rfc2131.c | 10 +-
 src/tftp.c|  2 +-
 src/util.c| 13 -
 11 files changed, 44 insertions(+), 26 deletions(-)

diff --git a/src/bpf.c b/src/bpf.c
index 49a11bf..ff66d6d 100644
--- a/src/bpf.c
+++ b/src/bpf.c
@@ -169,7 +169,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
 	  struct in6_ifreq ifr6;
 
 	  memset(&ifr6, 0, sizeof(ifr6));
-	  strncpy(ifr6.ifr_name, addrs->ifa_name, sizeof(ifr6.ifr_name));
+	  safe_strncpy(ifr6.ifr_name, addrs->ifa_name, sizeof(ifr6.ifr_name));
 	  
 	  ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr);
 	  if (fd != -1 && ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) != -1)
diff --git a/src/dhcp-common.c b/src/dhcp-common.c
index 8ff0f0d..78c1d9b 100644
--- a/src/dhcp-common.c
+++ b/src/dhcp-common.c
@@ -485,8 +485,11 @@ char *whichdevice(void)
  
 void  bindtodevice(char *device, int fd)
 {
+  size_t len = strlen(device)+1;
+  if (len > IFNAMSIZ)
+len = IFNAMSIZ;
   /* only allowed by root. */
-  if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, IFNAMSIZ) == -1 &&
+  if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, device, len) == -1 &&
   errno != EPERM)
 die(_("failed to set SO_BINDTODEVICE on DHCP socket: %s"), NULL, EC_BADNET);
 }
diff --git a/src/dhcp.c b/src/dhcp.c
index 4d29525..f8d323b 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -232,7 +232,7 @@ void dhcp_packet(time_t now, int pxe_fd)
   
 #ifdef HAVE_LINUX_NETWORK
   /* ARP fiddling uses original interface even if we pretend to use a different one. */
-  strncpy(arp_req.arp_dev, ifr.ifr_name, 16);
+  safe_strncpy(arp_req.arp_dev, ifr.ifr_name, sizeof(arp_req.arp_dev));
 #endif 
 
   /* If the interface on which the DHCP request was received is an
@@ -255,7 +255,7 @@ void dhcp_packet(time_t now, int pxe_fd)
 	  }
 	else 
 	  {
-		strncpy(ifr.ifr_name,  bridge->iface, IF_NAMESIZE);
+		safe_strncpy(ifr.ifr_name,  bridge->iface, sizeof(ifr.ifr_name));
 		break;
 	  }
 	  }
@@ -279,7 +279,7 @@ void dhcp_packet(time_t now, int pxe_fd)
   is_relay_reply = 1; 
   iov.iov_len = sz;
 #ifdef HAVE_LINUX_NETWORK
-  strncpy(arp_req.arp_dev, ifr.ifr_name, 16);
+  safe_strncpy(arp_req.arp_dev, ifr.ifr_name, sizeof(arp_req.arp_dev));
 #endif 
 }
   else
@@ -988,8 +988,7 @@ char *host_from_dns(struct in_addr addr)
   if (!legal_hostname(hostname))
 	return NULL;
   
-  strncpy(daemon->dhcp_buff, hostname, 256);
-  daemon->dhcp_buff[255] = 0;
+  safe_strncpy(daemon->dhcp_buff, hostname, 256);
   strip_hostname(daemon->dhcp_buff);
 
   return daemon->dhcp_buff;
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 4cf12bf..b260f8a 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1237,6 +1237,7 @@ int legal_hostname(char *name);
 char *canonicalise(char *in, int *nomem);
 unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit);
 void *safe_malloc(size_t size);
+void safe_strncpy(char *dest, const char *src, size_t size);
 void safe_pipe(int *fd, int read_noblock);
 void *whine_malloc(size_t size);
 int sa_len(union mysockaddr *addr);
diff --git a/src/log.c b/src/log.c
index dae8a75..d0d4780 100644
--- a/src/log.c
+++ b/src/log.c
@@ -232,7 +232

[Dnsmasq-discuss] [PATCH] dhcpv6: fix unaligned access crash on aarch64

2018-08-21 Thread Vladislav Grishenko
Hi, Simon

 

Faced with dnsmasq crash on aarch64 (32bit userspace, 
arm-buildroot-linux-gnueabi-gcc 5.3.0) with dhcpv6 stateful configured.

Unaligned packet’s req_addr is used in lease6_allocate() for struct copy since 
2.67test15 (commit 89500e31f199e9ae1eadc86213b911ff44d30d6f).

As for other places, seems well-aligned stack-local vars are used.

Please refer proposed patch attached and gdb trace:

 

Program received signal SIGBUS, Bus error.

0x0003f990 in lease6_allocate (addrp=0xa55e6, lease_type=32) at lease.c:822

822   lease->addr6 = *addrp;

(gdb) bt

#0  0x0003f990 in lease6_allocate (addrp=0xa55e6, lease_type=32) at lease.c:822

#1  0x00055fac in update_leases (state=0xfffef8ac, context=0xa7ee8, 
addr=0xa55e6, lease_time=900, now=14609) at rfc3315.c:1825

#2  0x00055ab4 in add_address (state=0xfffef8ac, context=0xa7ee8, 
lease_time=900, ia_option=0xa55e2, min_time=0xfffef6d0, addr=0xa55e6, 
now=14609) at rfc3315.c:1684

#3  0x00053764 in dhcp6_no_relay (state=0xfffef8ac, msg_type=3, inbuff=0xa55a8, 
sz=128, is_unicast=0, now=14609) at rfc3315.c:938

#4  0x00051744 in dhcp6_maybe_relay (state=0xfffef8ac, inbuff=0xa55a8, sz=128, 
client_addr=0xfffef9a0, is_unicast=0, now=14609) at rfc3315.c:172

#5  0x000513b8 in dhcp6_reply (context=0xa7ee8, interface=23, 
iface_name=0xfffef978, fallback=0xfffef9f8, ll_addr=0xfffefa18, 
ula_addr=0xfffefa28, sz=128, client_addr=0xfffef9a0,

now=14609) at rfc3315.c:103

#6  0x0004f4b4 in dhcp6_packet (now=14609) at dhcp6.c:233

#7  0x00038c78 in main (argc=3, argv=0xfffefd34) at dnsmasq.c:1099

 

Best Regards, Vladislav Grishenko

 



0001-dhcpv6-fix-unaligned-access-crash-on-aarch64.patch
Description: Binary data
___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss