So a while back Alexander Markert sent a bug report regarding sendmsg()
behaviour with IP_SENDSRCADDR :

https://marc.info/?l=openbsd-tech&m=149276833923905&w=2

This impacts our dnsmasq port :

https://marc.info/?l=openbsd-tech&m=149234052220818&w=2

Alexander Markert shows in the first thread the problematic code and
conditions.

To save you the trip back in time : sendfrom() returns EWOULDBLOCK (or
blocks if using blocking IO) when len(cmsg) + len(data) >
len(socket.buffer). The better behaviour would be to never block and
return EMSGSIZE.

The first diff fixes the kernel code ; The second diff reverts
https://marc.info/?l=openbsd-ports-cvs&m=149233921320572&w=2 and fixes
a bad cmsg setup.

1) Can you confirm this fixes dnsmasq ? or whatever you used to trigger
  the bug ?

2) Ok ?


(apologies for the delay by the way :S )

-- 8< ---- 8< ---- 8< --

Index: sys/kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.224
diff -u -p -r1.224 uipc_socket.c
--- sys/kern/uipc_socket.c      14 Jun 2018 08:46:09 -0000
1.224 +++ sys/kern/uipc_socket.c        26 Jun 2018 18:51:49 -0000
@@ -459,9 +459,10 @@ restart:
                space = sbspace(so, &so->so_snd);
                if (flags & MSG_OOB)
                        space += 1024;
-               if ((atomic && resid > so->so_snd.sb_hiwat) ||
+               if ((so->so_proto->pr_domain->dom_family == AF_UNIX &&
+                   atomic && resid > so->so_snd.sb_hiwat) ||
                    (so->so_proto->pr_domain->dom_family != AF_UNIX &&
-                   clen > so->so_snd.sb_hiwat))
+                   clen + (atomic ? resid : 0) > so->so_snd.sb_hiwat))
                        snderr(EMSGSIZE);
                if (space < clen ||
                    (space - clen < resid &&



-- 8< ---- 8< ---- 8< --


Index: net/dnsmasq/patches/patch-src_dnsmasq_c
===================================================================
RCS file: net/dnsmasq/patches/patch-src_dnsmasq_c
diff -N net/dnsmasq/patches/patch-src_dnsmasq_c
--- net/dnsmasq/patches/patch-src_dnsmasq_c     29 Mar 2018 19:42:51 -0000      
1.5
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,16 +0,0 @@
-$OpenBSD: patch-src_dnsmasq_c,v 1.5 2018/03/29 19:42:51 ajacoutot Exp $
-
-Fails. Currently disabled pending investigation.
-
-Index: src/dnsmasq.c
---- src/dnsmasq.c.orig
-+++ src/dnsmasq.c
-@@ -149,7 +149,7 @@ int main (int argc, char **argv)
-       open("/dev/null", O_RDWR); 
- 
- #ifndef HAVE_LINUX_NETWORK
--#  if !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && 
defined(IP_SENDSRCADDR))
-+#  if defined(__OpenBSD__) || !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) 
&& defined(IP_SENDSRCADDR))
-   if (!option_bool(OPT_NOWILD))
-     {
-       bind_fallback = 1;
Index: net/dnsmasq/patches/patch-src_forward_c
===================================================================
RCS file: /cvs/ports/net/dnsmasq/patches/patch-src_forward_c,v
retrieving revision 1.1
diff -u -p -r1.1 patch-src_forward_c
--- net/dnsmasq/patches/patch-src_forward_c     16 Apr 2017 10:40:07 -0000      
1.1
+++ net/dnsmasq/patches/patch-src_forward_c     26 Jun 2018 18:48:17 -0000
@@ -1,24 +1,17 @@
-$OpenBSD: patch-src_forward_c,v 1.1 2017/04/16 10:40:07 sthen Exp $
+$OpenBSD$
 
-Fails. Currently disabled pending investigation.
+CMSG_SPACE() != CMSG_LEN()
 
---- src/forward.c.orig Sat Apr 15 22:36:04 2017
-+++ src/forward.c      Sat Apr 15 22:46:09 2017
-@@ -35,7 +35,7 @@ int send_from(int fd, int nowild, char *packet, size_t
-     struct cmsghdr align; /* this ensures alignment */
- #if defined(HAVE_LINUX_NETWORK)
-     char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
--#elif defined(IP_SENDSRCADDR)
-+#elif !defined(__OpenBSD__) && defined(IP_SENDSRCADDR)
-     char control[CMSG_SPACE(sizeof(struct in_addr))];
- #endif
- #ifdef HAVE_IPV6
-@@ -71,7 +71,7 @@ int send_from(int fd, int nowild, char *packet, size_t
-         msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct 
in_pktinfo));
-         cmptr->cmsg_level = IPPROTO_IP;
+Index: src/forward.c
+--- src/forward.c.orig
++++ src/forward.c
+@@ -73,7 +73,8 @@ int send_from(int fd, int nowild, char *packet, size_t
          cmptr->cmsg_type = IP_PKTINFO;
--#elif defined(IP_SENDSRCADDR)
-+#elif !defined(__OpenBSD__) && defined(IP_SENDSRCADDR)
+ #elif defined(IP_SENDSRCADDR)
          memcpy(CMSG_DATA(cmptr), &(source->addr.addr4), 
sizeof(source->addr.addr4));
-         msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct 
in_addr));
+-        msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct 
in_addr));
++        msg.msg_controllen = sizeof(control_u.control);
++        cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
          cmptr->cmsg_level = IPPROTO_IP;
+         cmptr->cmsg_type = IP_SENDSRCADDR;
+ #endif

Reply via email to