diff options
author | Matt Macy <mmacy@FreeBSD.org> | 2018-06-21 20:18:23 +0000 |
---|---|---|
committer | Matt Macy <mmacy@FreeBSD.org> | 2018-06-21 20:18:23 +0000 |
commit | e93fdbe2126dced3ce717c3c1fd5d600dd60f3e4 (patch) | |
tree | 3d9f99d566da8ccad28adf6a52eeb1b871d9d5b3 /sys/netinet | |
parent | 3d348772e7eb76d343d5deb417453db3a694c1d1 (diff) | |
download | src-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.c | 58 |
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) { |