aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/in_pcb.c
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2023-07-27 03:35:30 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2023-07-27 03:35:30 +0000
commita43e7a96b64e4bda98f49471de33f3ec5c242a2c (patch)
treec801556a9680c2711dd027252245ea87b7ccd8f7 /sys/netinet/in_pcb.c
parent474708c334a7d4fb27049e7dabaf5b74542568dd (diff)
downloadsrc-a43e7a96b64e4bda98f49471de33f3ec5c242a2c.tar.gz
src-a43e7a96b64e4bda98f49471de33f3ec5c242a2c.zip
inpcb: use internal flag to mark pcbs that are inserted into lbgroup
Using INP_REUSEPORT_LB is unsafe, as it is basically a copy of socket's SO_REUSEPORT_LB flag, which can be cleared by userland after bind(). Reviewed by: markj Reported by: syzbot+e7d2e451f89fb444319b@syzkaller.appspotmail.com Differential Revision: https://reviews.freebsd.org/D41197
Diffstat (limited to 'sys/netinet/in_pcb.c')
-rw-r--r--sys/netinet/in_pcb.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 5fddff89dd0a..44775e21e201 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -113,7 +113,9 @@ __FBSDID("$FreeBSD$");
#define INPCBLBGROUP_SIZMIN 8
#define INPCBLBGROUP_SIZMAX 256
-#define INP_FREED 0x00000200 /* See in_pcb.h. */
+
+#define INP_FREED 0x00000200 /* Went through in_pcbfree(). */
+#define INP_INLBGROUP 0x01000000 /* Inserted into inpcblbgroup. */
/*
* These configure the range of local port addresses assigned to
@@ -403,6 +405,7 @@ in_pcbinslbgrouphash(struct inpcb *inp, uint8_t numa_domain)
grp->il_inp[grp->il_inpcnt] = inp;
grp->il_inpcnt++;
+ inp->inp_flags |= INP_INLBGROUP;
return (0);
}
@@ -420,6 +423,7 @@ in_pcbremlbgrouphash(struct inpcb *inp)
pcbinfo = inp->inp_pcbinfo;
INP_WLOCK_ASSERT(inp);
+ MPASS(inp->inp_flags & INP_INLBGROUP);
INP_HASH_WLOCK_ASSERT(pcbinfo);
hdr = &pcbinfo->ipi_lbgrouphashbase[
@@ -436,9 +440,11 @@ in_pcbremlbgrouphash(struct inpcb *inp)
/* Pull up inpcbs, shrink group if possible. */
in_pcblbgroup_reorder(hdr, &grp, i);
}
+ inp->inp_flags &= ~INP_INLBGROUP;
return;
}
}
+ KASSERT(0, ("%s: did not find %p", __func__, inp));
}
int
@@ -2672,7 +2678,7 @@ in_pcbinshash(struct inpcb *inp)
if (phd == NULL) {
phd = uma_zalloc_smr(pcbinfo->ipi_portzone, M_NOWAIT);
if (phd == NULL) {
- if ((inp->inp_flags2 & INP_REUSEPORT_LB) != 0)
+ if ((inp->inp_flags & INP_INLBGROUP) != 0)
in_pcbremlbgrouphash(inp);
return (ENOMEM);
}
@@ -2717,7 +2723,7 @@ in_pcbremhash_locked(struct inpcb *inp)
INP_HASH_WLOCK_ASSERT(inp->inp_pcbinfo);
MPASS(inp->inp_flags & INP_INHASHLIST);
- if ((inp->inp_flags2 & INP_REUSEPORT_LB) != 0)
+ if ((inp->inp_flags & INP_INLBGROUP) != 0)
in_pcbremlbgrouphash(inp);
#ifdef INET6
if (inp->inp_vflag & INP_IPV6) {