Eliminate use of the global ripsrc which was being used to pass address
information from rip_input() to rip_append(). Instead, pass the source address for an IP datagram to rip_append() using a stack-allocated sockaddr_in, similar to udp_input() and udp_append(). Prior to the move to rwlocks for inpcbinfo, this was not a problem, as use of the global was synchronized using the ripcbinfo mutex, but with read-locking there is the potential for a race during concurrent receive. This problem is not present in the IPv6 raw IP socket code, which already used a stack variable for the address. Spotted by: mav MFC after: 1 week (before inpcbinfo rwlock changes)
This commit is contained in:
parent
694382c8eb
commit
3b19fa3597
@ -153,10 +153,9 @@ rip_init(void)
|
||||
EVENTHANDLER_PRI_ANY);
|
||||
}
|
||||
|
||||
static struct sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET };
|
||||
|
||||
static int
|
||||
rip_append(struct inpcb *last, struct ip *ip, struct mbuf *n)
|
||||
rip_append(struct inpcb *last, struct ip *ip, struct mbuf *n,
|
||||
struct sockaddr_in *ripsrc)
|
||||
{
|
||||
int policyfail = 0;
|
||||
|
||||
@ -185,7 +184,7 @@ rip_append(struct inpcb *last, struct ip *ip, struct mbuf *n)
|
||||
ip_savecontrol(last, &opts, ip, n);
|
||||
SOCKBUF_LOCK(&so->so_rcv);
|
||||
if (sbappendaddr_locked(&so->so_rcv,
|
||||
(struct sockaddr *)&ripsrc, n, opts) == 0) {
|
||||
(struct sockaddr *)ripsrc, n, opts) == 0) {
|
||||
/* should notify about lost packet */
|
||||
m_freem(n);
|
||||
if (opts)
|
||||
@ -208,10 +207,14 @@ rip_input(struct mbuf *m, int off)
|
||||
struct ip *ip = mtod(m, struct ip *);
|
||||
int proto = ip->ip_p;
|
||||
struct inpcb *inp, *last;
|
||||
struct sockaddr_in ripsrc;
|
||||
|
||||
INP_INFO_RLOCK(&ripcbinfo);
|
||||
bzero(&ripsrc, sizeof(ripsrc));
|
||||
ripsrc.sin_len = sizeof(ripsrc);
|
||||
ripsrc.sin_family = AF_INET;
|
||||
ripsrc.sin_addr = ip->ip_src;
|
||||
last = NULL;
|
||||
INP_INFO_RLOCK(&ripcbinfo);
|
||||
LIST_FOREACH(inp, &ripcb, inp_list) {
|
||||
INP_RLOCK(inp);
|
||||
if (inp->inp_ip_p && inp->inp_ip_p != proto) {
|
||||
@ -238,14 +241,14 @@ rip_input(struct mbuf *m, int off)
|
||||
|
||||
n = m_copy(m, 0, (int)M_COPYALL);
|
||||
if (n != NULL)
|
||||
(void) rip_append(last, ip, n);
|
||||
(void) rip_append(last, ip, n, &ripsrc);
|
||||
/* XXX count dropped packet */
|
||||
INP_RUNLOCK(last);
|
||||
}
|
||||
last = inp;
|
||||
}
|
||||
if (last != NULL) {
|
||||
if (rip_append(last, ip, m) != 0)
|
||||
if (rip_append(last, ip, m, &ripsrc) != 0)
|
||||
ipstat.ips_delivered--;
|
||||
INP_RUNLOCK(last);
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user