Fix synchronization in the IPV6_2292PKTOPTIONS set handler.
The inpcb needs to be locked when we update output packet options. Otherwise it is possible for the IPV6_2292PKTOPTIONS handler to free packet option structures while another thread is reading or updating them. Note that the option handler is still kind of broken. For instance it frees all options before performing privilege checks for individual options. However, this can be fixed separately. Reported by: syzbot+52eb0fd4ddc119787f9d@syzkaller.appspotmail.com Reviewed by: bz, tuexen MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D24125
This commit is contained in:
parent
3a22819456
commit
5707de0ed8
@ -1694,8 +1694,10 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
error = soopt_mcopyin(sopt, m); /* XXX */
|
||||
if (error != 0)
|
||||
break;
|
||||
error = ip6_pcbopts(&inp->in6p_outputopts,
|
||||
m, so, sopt);
|
||||
INP_WLOCK(inp);
|
||||
error = ip6_pcbopts(&inp->in6p_outputopts, m,
|
||||
so, sopt);
|
||||
INP_WUNLOCK(inp);
|
||||
m_freem(m); /* XXX */
|
||||
break;
|
||||
}
|
||||
@ -2458,8 +2460,11 @@ ip6_pcbopts(struct ip6_pktopts **pktopt, struct mbuf *m,
|
||||
printf("ip6_pcbopts: all specified options are cleared.\n");
|
||||
#endif
|
||||
ip6_clearpktopts(opt, -1);
|
||||
} else
|
||||
opt = malloc(sizeof(*opt), M_IP6OPT, M_WAITOK);
|
||||
} else {
|
||||
opt = malloc(sizeof(*opt), M_IP6OPT, M_NOWAIT);
|
||||
if (opt == NULL)
|
||||
return (ENOMEM);
|
||||
}
|
||||
*pktopt = NULL;
|
||||
|
||||
if (!m || m->m_len == 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user