Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
raw IPv6 inp_cksum6 inp_icmp6filt
To:
tech@openbsd.org
Date:
Tue, 16 Apr 2024 19:46:00 +0200

Download raw body.

Thread
  • Alexander Bluhm:

    raw IPv6 inp_cksum6 inp_icmp6filt

Hi,

Document that both inp_cksum6 and inp_icmp6filt are protected by
net lock.  The inp_icmp6filt is ignored if the pointer is NULL, but
it is always set during attach.  Better allocate the ICMP6 filter
only when used in icmp6_ctloutput().

ok?

bluhm

Index: netinet/in_pcb.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/in_pcb.h,v
diff -u -p -r1.155 in_pcb.h
--- netinet/in_pcb.h	15 Apr 2024 18:31:04 -0000	1.155
+++ netinet/in_pcb.h	16 Apr 2024 14:40:25 -0000
@@ -175,9 +175,9 @@ struct inpcb {
 #define inp_ip6_minhlim inp_ip_minttl	/* minimum Hop Limit or drop */
 #define	inp_flowinfo	inp_hu.hu_ipv6.ip6_flow
 
-	int	inp_cksum6;
-	struct	icmp6_filter *inp_icmp6filt;
-	struct	pf_state_key *inp_pf_sk; /* [L] */
+	int	inp_cksum6;			/* [N] */
+	struct	icmp6_filter *inp_icmp6filt;	/* [N] */
+	struct	pf_state_key *inp_pf_sk;	/* [L] */
 	struct	mbuf *(*inp_upcall)(void *, struct mbuf *,
 		    struct ip *, struct ip6_hdr *, void *, int);
 	void	*inp_upcall_arg;
Index: netinet6/icmp6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/icmp6.c,v
diff -u -p -r1.251 icmp6.c
--- netinet6/icmp6.c	3 Dec 2023 20:36:24 -0000	1.251
+++ netinet6/icmp6.c	16 Apr 2024 14:40:25 -0000
@@ -1702,24 +1702,20 @@ icmp6_ctloutput(int op, struct socket *s
 	case PRCO_SETOPT:
 		switch (optname) {
 		case ICMP6_FILTER:
-		    {
-			struct icmp6_filter *p;
-
-			if (m == NULL || m->m_len != sizeof(*p)) {
+			if (m == NULL ||
+			    m->m_len != sizeof(struct icmp6_filter)) {
 				error = EMSGSIZE;
 				break;
 			}
-			p = mtod(m, struct icmp6_filter *);
-			if (!p || !inp->inp_icmp6filt) {
-				error = EINVAL;
-				break;
+			if (inp->inp_icmp6filt == NULL) {
+				inp->inp_icmp6filt = malloc(
+				    sizeof(struct icmp6_filter), M_PCB,
+				    M_WAITOK);
 			}
-			bcopy(p, inp->inp_icmp6filt,
-				sizeof(struct icmp6_filter));
-			error = 0;
+			memcpy(inp->inp_icmp6filt,
+			    mtod(m, struct icmp6_filter *),
+			    sizeof(struct icmp6_filter));
 			break;
-		    }
-
 		default:
 			error = ENOPROTOOPT;
 			break;
@@ -1729,21 +1725,16 @@ icmp6_ctloutput(int op, struct socket *s
 	case PRCO_GETOPT:
 		switch (optname) {
 		case ICMP6_FILTER:
-		    {
-			struct icmp6_filter *p;
-
-			if (!inp->inp_icmp6filt) {
-				error = EINVAL;
+			m->m_len = sizeof(struct icmp6_filter);
+			if (inp->inp_icmp6filt == NULL) {
+				ICMP6_FILTER_SETPASSALL(
+				    mtod(m, struct icmp6_filter *));
 				break;
 			}
-			m->m_len = sizeof(struct icmp6_filter);
-			p = mtod(m, struct icmp6_filter *);
-			bcopy(inp->inp_icmp6filt, p,
-				sizeof(struct icmp6_filter));
-			error = 0;
+			memcpy(mtod(m, struct icmp6_filter *),
+			    inp->inp_icmp6filt,
+			    sizeof(struct icmp6_filter));
 			break;
-		    }
-
 		default:
 			error = ENOPROTOOPT;
 			break;
Index: netinet6/raw_ip6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/raw_ip6.c,v
diff -u -p -r1.183 raw_ip6.c
--- netinet6/raw_ip6.c	16 Apr 2024 12:40:40 -0000	1.183
+++ netinet6/raw_ip6.c	16 Apr 2024 14:40:25 -0000
@@ -207,7 +207,7 @@ rip6_input(struct mbuf **mp, int *offp, 
 		if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6) &&
 		    !IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6, &ip6->ip6_src))
 			continue;
-		if (proto == IPPROTO_ICMPV6 && inp->inp_icmp6filt) {
+		if (proto == IPPROTO_ICMPV6 && inp->inp_icmp6filt != NULL) {
 			if (ICMP6_FILTER_WILLBLOCK(type, inp->inp_icmp6filt))
 				continue;
 		}
@@ -613,13 +613,6 @@ rip6_attach(struct socket *so, int proto
 	inp->inp_ipv6.ip6_nxt = proto;
 	inp->inp_cksum6 = -1;
 
-	inp->inp_icmp6filt = malloc(sizeof(struct icmp6_filter), M_PCB,
-	    wait == M_WAIT ? M_WAITOK : M_NOWAIT);
-	if (inp->inp_icmp6filt == NULL) {
-		in_pcbdetach(inp);
-		return ENOMEM;
-	}
-	ICMP6_FILTER_SETPASSALL(inp->inp_icmp6filt);
 	return 0;
 }