Simple locking fixes in ip_ctloutput, ip6_ctloutput, rip_ctloutput.
Submitted by: Jason Eggleston <jason@eggnet.com> Sponsored by: Limelight Networks Differential Revision: https://reviews.freebsd.org/D14624
This commit is contained in:
parent
397b9e40e9
commit
2a499acf59
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=331379
@ -1314,12 +1314,14 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
break;
|
||||
|
||||
case IP_PORTRANGE:
|
||||
INP_RLOCK(inp);
|
||||
if (inp->inp_flags & INP_HIGHPORT)
|
||||
optval = IP_PORTRANGE_HIGH;
|
||||
else if (inp->inp_flags & INP_LOWPORT)
|
||||
optval = IP_PORTRANGE_LOW;
|
||||
else
|
||||
optval = 0;
|
||||
INP_RUNLOCK(inp);
|
||||
break;
|
||||
|
||||
case IP_ONESBCAST:
|
||||
@ -1345,9 +1347,11 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
break;
|
||||
#ifdef RSS
|
||||
case IP_RSSBUCKETID:
|
||||
INP_RLOCK(inp);
|
||||
retval = rss_hash2bucket(inp->inp_flowid,
|
||||
inp->inp_flowtype,
|
||||
&rss_bucket);
|
||||
INP_RUNLOCK(inp);
|
||||
if (retval == 0)
|
||||
optval = rss_bucket;
|
||||
else
|
||||
|
@ -639,10 +639,12 @@ rip_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
sizeof optval);
|
||||
if (error)
|
||||
break;
|
||||
INP_WLOCK(inp);
|
||||
if (optval)
|
||||
inp->inp_flags |= INP_HDRINCL;
|
||||
else
|
||||
inp->inp_flags &= ~INP_HDRINCL;
|
||||
INP_WUNLOCK(inp);
|
||||
break;
|
||||
|
||||
case IP_FW3: /* generic ipfw v.3 functions */
|
||||
|
@ -1498,8 +1498,10 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
error = soopt_mcopyin(sopt, m); /* XXX */
|
||||
if (error != 0)
|
||||
break;
|
||||
INP_WLOCK(in6p);
|
||||
error = ip6_pcbopts(&in6p->in6p_outputopts,
|
||||
m, so, sopt);
|
||||
INP_WUNLOCK(in6p);
|
||||
m_freem(m); /* XXX */
|
||||
break;
|
||||
}
|
||||
@ -1635,11 +1637,13 @@ do { \
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
INP_WLOCK(in6p);
|
||||
optp = &in6p->in6p_outputopts;
|
||||
error = ip6_pcbopt(IPV6_HOPLIMIT,
|
||||
(u_char *)&optval, sizeof(optval),
|
||||
optp, (td != NULL) ? td->td_ucred :
|
||||
NULL, uproto);
|
||||
INP_WUNLOCK(in6p);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1690,8 +1694,10 @@ do { \
|
||||
* available only prior to bind(2).
|
||||
* see ipng mailing list, Jun 22 2001.
|
||||
*/
|
||||
INP_WLOCK(in6p);
|
||||
if (in6p->inp_lport ||
|
||||
!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
|
||||
INP_WUNLOCK(in6p);
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
@ -1700,6 +1706,7 @@ do { \
|
||||
in6p->inp_vflag &= ~INP_IPV4;
|
||||
else
|
||||
in6p->inp_vflag |= INP_IPV4;
|
||||
INP_WUNLOCK(in6p);
|
||||
break;
|
||||
case IPV6_RECVTCLASS:
|
||||
/* cannot mix with RFC2292 XXX */
|
||||
@ -1749,11 +1756,13 @@ do { \
|
||||
break;
|
||||
{
|
||||
struct ip6_pktopts **optp;
|
||||
INP_WLOCK(in6p);
|
||||
optp = &in6p->in6p_outputopts;
|
||||
error = ip6_pcbopt(optname,
|
||||
(u_char *)&optval, sizeof(optval),
|
||||
optp, (td != NULL) ? td->td_ucred :
|
||||
NULL, uproto);
|
||||
INP_WUNLOCK(in6p);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1818,12 +1827,6 @@ do { \
|
||||
int optlen;
|
||||
struct ip6_pktopts **optp;
|
||||
|
||||
/* cannot mix with RFC2292 */
|
||||
if (OPTBIT(IN6P_RFC2292)) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We only ensure valsize is not too large
|
||||
* here. Further validation will be done
|
||||
@ -1833,12 +1836,21 @@ do { \
|
||||
sizeof(optbuf_storage), 0);
|
||||
if (error)
|
||||
break;
|
||||
|
||||
INP_WLOCK(in6p);
|
||||
/* cannot mix with RFC2292 */
|
||||
if (OPTBIT(IN6P_RFC2292)) {
|
||||
INP_WUNLOCK(in6p);
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
optlen = sopt->sopt_valsize;
|
||||
optbuf = optbuf_storage;
|
||||
optp = &in6p->in6p_outputopts;
|
||||
error = ip6_pcbopt(optname, optbuf, optlen,
|
||||
optp, (td != NULL) ? td->td_ucred : NULL,
|
||||
uproto);
|
||||
INP_WUNLOCK(in6p);
|
||||
break;
|
||||
}
|
||||
#undef OPTSET
|
||||
@ -2023,10 +2035,12 @@ do { \
|
||||
break;
|
||||
#ifdef RSS
|
||||
case IPV6_RSSBUCKETID:
|
||||
INP_RLOCK(in6p);
|
||||
retval =
|
||||
rss_hash2bucket(in6p->inp_flowid,
|
||||
in6p->inp_flowtype,
|
||||
&rss_bucket);
|
||||
INP_RUNLOCK(in6p);
|
||||
if (retval == 0)
|
||||
optval = rss_bucket;
|
||||
else
|
||||
@ -2230,6 +2244,8 @@ ip6_pcbopts(struct ip6_pktopts **pktopt, struct mbuf *m,
|
||||
int error = 0;
|
||||
struct thread *td = sopt->sopt_td;
|
||||
|
||||
INP_WLOCK_ASSERT(sotoinpcb(so));
|
||||
|
||||
/* turn off any old options. */
|
||||
if (opt) {
|
||||
#ifdef DIAGNOSTIC
|
||||
@ -3074,6 +3090,8 @@ ip6_optlen(struct inpcb *in6p)
|
||||
{
|
||||
int len;
|
||||
|
||||
INP_WLOCK_ASSERT(in6p);
|
||||
|
||||
if (!in6p->in6p_outputopts)
|
||||
return 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user