aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorMatt Macy <mmacy@FreeBSD.org>2018-06-21 20:18:23 +0000
committerMatt Macy <mmacy@FreeBSD.org>2018-06-21 20:18:23 +0000
commite93fdbe2126dced3ce717c3c1fd5d600dd60f3e4 (patch)
tree3d9f99d566da8ccad28adf6a52eeb1b871d9d5b3 /sys/netinet
parent3d348772e7eb76d343d5deb417453db3a694c1d1 (diff)
downloadsrc-e93fdbe2126dced3ce717c3c1fd5d600dd60f3e4.tar.gz
src-e93fdbe2126dced3ce717c3c1fd5d600dd60f3e4.zip
raw_ip: validate inp in both loops
Continuation of r335497. Also move the lock acquisition up to validate before referencing inp_cred. Reported by: pho
Notes
Notes: svn path=/head/; revision=335501
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/raw_ip.c58
1 files changed, 33 insertions, 25 deletions
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index ff2c355fb21e..bee48dcfe5c6 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -312,29 +312,31 @@ rip_input(struct mbuf **mp, int *offp, int proto)
continue;
if (inp->inp_faddr.s_addr != ip->ip_src.s_addr)
continue;
- if (jailed_without_vnet(inp->inp_cred)) {
- /*
- * XXX: If faddr was bound to multicast group,
- * jailed raw socket will drop datagram.
- */
- if (prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
- continue;
- }
if (last != NULL) {
struct mbuf *n;
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
if (n != NULL)
- (void) rip_append(last, ip, n, &ripsrc);
+ (void) rip_append(last, ip, n, &ripsrc);
/* XXX count dropped packet */
INP_RUNLOCK(last);
+ last = NULL;
}
INP_RLOCK(inp);
- last = inp;
- if (__predict_false(inp->inp_flags2 & INP_FREED)) {
- last = NULL;
- INP_RUNLOCK(inp);
+ if (__predict_false(inp->inp_flags2 & INP_FREED))
+ goto skip_1;
+ if (jailed_without_vnet(inp->inp_cred)) {
+ /*
+ * XXX: If faddr was bound to multicast group,
+ * jailed raw socket will drop datagram.
+ */
+ if (prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
+ goto skip_1;
}
+ last = inp;
+ continue;
+ skip_1:
+ INP_RUNLOCK(inp);
}
CK_LIST_FOREACH(inp, &V_ripcbinfo.ipi_hashbase[0], inp_hash) {
if (inp->inp_ip_p && inp->inp_ip_p != proto)
@@ -350,6 +352,19 @@ rip_input(struct mbuf **mp, int *offp, int proto)
if (!in_nullhost(inp->inp_faddr) &&
!in_hosteq(inp->inp_faddr, ip->ip_src))
continue;
+ if (last != NULL) {
+ struct mbuf *n;
+
+ n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
+ if (n != NULL)
+ (void) rip_append(last, ip, n, &ripsrc);
+ /* XXX count dropped packet */
+ INP_RUNLOCK(last);
+ last = NULL;
+ }
+ INP_RLOCK(inp);
+ if (__predict_false(inp->inp_flags2 & INP_FREED))
+ goto skip_2;
if (jailed_without_vnet(inp->inp_cred)) {
/*
* Allow raw socket in jail to receive multicast;
@@ -358,7 +373,7 @@ rip_input(struct mbuf **mp, int *offp, int proto)
*/
if (!IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) &&
prison_check_ip4(inp->inp_cred, &ip->ip_dst) != 0)
- continue;
+ goto skip_2;
}
/*
* If this raw socket has multicast state, and we
@@ -399,20 +414,13 @@ rip_input(struct mbuf **mp, int *offp, int proto)
if (blocked != MCAST_PASS) {
IPSTAT_INC(ips_notmember);
- continue;
+ goto skip_2;
}
}
- if (last != NULL) {
- struct mbuf *n;
-
- n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
- if (n != NULL)
- (void) rip_append(last, ip, n, &ripsrc);
- /* XXX count dropped packet */
- INP_RUNLOCK(last);
- }
- INP_RLOCK(inp);
last = inp;
+ continue;
+ skip_2:
+ INP_RUNLOCK(inp);
}
INP_INFO_RUNLOCK(&V_ripcbinfo);
if (last != NULL) {