relayd: accept icmp packets with IP options

Marc Jorge <[email protected]>
Newsgroups gmane.os.openbsd.tech
Message-ID <[email protected]>
Hello,

We're currently assuming a fixed 20-byte IP header in recv_icmp, which 
breaks if a packet drops in with IP options.


Index: usr.sbin/relayd/check_icmp.c
===================================================================
RCS file: /cvs/src/usr.sbin/relayd/check_icmp.c,v
diff -u -p -u -r1.50 check_icmp.c
--- usr.sbin/relayd/check_icmp.c	15 Jun 2026 11:02:13 -0000	1.50
+++ usr.sbin/relayd/check_icmp.c	13 Aug 2026 15:38:54 -0000
@@ -286,11 +286,13 @@ void
  recv_icmp(int s, short event, void *arg)
  {
  	struct ctl_icmp_event	*cie = arg;
-	u_char			 packet[ICMP_BUF_SIZE];
+	u_char			 packet[ICMP_BUF_SIZE + 40];	/* 40 bytes for reserved IP 
options */
  	socklen_t		 slen;
  	struct sockaddr_storage	 ss;
+	struct ip		*ip;
  	struct icmp		*icp;
  	struct icmp6_hdr	*icp6;
+	u_int			 hlen;
  	u_int16_t		 icpid;
  	struct host		*host;
  	ssize_t			 r;
@@ -307,17 +309,25 @@ recv_icmp(int s, short event, void *arg)

  	r = recvfrom(s, packet, sizeof(packet), 0,
  	    (struct sockaddr *)&ss, &slen);
-	if (r == -1 || r != ICMP_BUF_SIZE) {
-		if (r == -1 && errno != EAGAIN && errno != EINTR)
+	if (r == -1) {
+		if (errno != EAGAIN && errno != EINTR)
  			log_debug("%s: receive error", __func__);
  		goto retry;
  	}

  	if (cie->af == AF_INET) {
-		icp = (struct icmp *)(packet + sizeof(struct ip));
+		if (r < (ssize_t)sizeof(*ip))
+			goto retry;
+		ip = (struct ip *)packet;
+		hlen = ip->ip_hl << 2;
+		if (hlen < sizeof(*ip) || r < (ssize_t)(hlen + sizeof(*icp)))
+			goto retry;
+		icp = (struct icmp *)(packet + hlen);
  		icpid = ntohs(icp->icmp_id);
  		id = icp->icmp_mask;
  	} else {
+		if (r < (ssize_t)(sizeof(*icp6) + sizeof(id)))
+			goto retry;
  		icp6 = (struct icmp6_hdr *)packet;
  		icpid = ntohs(icp6->icmp6_id);
  		memcpy(&id, packet + sizeof(*icp6), sizeof(id));
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.