diff options
author | Kristof Provost <kp@FreeBSD.org> | 2021-12-15 13:53:41 +0000 |
---|---|---|
committer | Kristof Provost <kp@FreeBSD.org> | 2021-12-17 16:30:36 +0000 |
commit | 9f5432d5e5f0ef9e034ad3da9fe6b1cf876ae68f (patch) | |
tree | 423013dda8300a153c8b53f3f6f1fe46625ea798 | |
parent | 266cbbfc65263a3b8bc7c95dd3d589aab7cefe7f (diff) | |
download | src-9f5432d5e5f0ef9e034ad3da9fe6b1cf876ae68f.tar.gz src-9f5432d5e5f0ef9e034ad3da9fe6b1cf876ae68f.zip |
netinet6: ip6_setpktopt() requires NET_EPOCH
ip6_setpktopt() can call ifnet_byindex() which requires epoch. Mark the
function as requiring NET_EPOCH, and ensure we enter it priot to calling
it.
Reported-by: syzbot+92526116441688fea8a3@syzkaller.appspotmail.com
Reviewed by: glebius
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D33462
-rw-r--r-- | sys/netinet6/ip6_output.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 7d8793b691b4..848ec6694398 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -2546,7 +2546,9 @@ static int ip6_pcbopt(int optname, u_char *buf, int len, struct ip6_pktopts **pktopt, struct ucred *cred, int uproto) { + struct epoch_tracker et; struct ip6_pktopts *opt; + int ret; if (*pktopt == NULL) { *pktopt = malloc(sizeof(struct ip6_pktopts), M_IP6OPT, @@ -2557,7 +2559,11 @@ ip6_pcbopt(int optname, u_char *buf, int len, struct ip6_pktopts **pktopt, } opt = *pktopt; - return (ip6_setpktopt(optname, buf, len, opt, cred, 1, 0, uproto)); + NET_EPOCH_ENTER(et); + ret = ip6_setpktopt(optname, buf, len, opt, cred, 1, 0, uproto); + NET_EPOCH_EXIT(et); + + return (ret); } #define GET_PKTOPT_VAR(field, lenexpr) do { \ @@ -2886,6 +2892,8 @@ ip6_setpktopt(int optname, u_char *buf, int len, struct ip6_pktopts *opt, int minmtupolicy, preftemp; int error; + NET_EPOCH_ASSERT(); + if (!sticky && !cmsg) { #ifdef DIAGNOSTIC printf("ip6_setpktopt: impossible case\n"); |