summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2021-12-15 15:58:02 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2021-12-15 15:58:02 +0000
commit54afa98178fb15e5d3de8a1396e50998ee09ebe7 (patch)
treea776e2bfb595c3fe18982f72111890f5690eaa23 /sys
parent2146bba213948527b5b5fda699eac2ea28cc2476 (diff)
Syzkaller found a dereference in igmp_leavegroup() where inm->inm_rti
is NULL. It should be set in rti_fill(), but is not if malloc(9) fails. There is no rollback after malloc failure so the field stays uninitialized. The code is only called from ioctl, setsockopt or a task. Malloc should wait instead of failing, otherwise syscalls would be unreliable. While there also put an M_WAIT in the init code. During init malloc must not fail. OK mvs@ Reported-by: syzbot+e22326057ccf34908d78@syzkaller.appspotmail.com
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/igmp.c18
1 files changed, 4 insertions, 14 deletions
diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c
index 017713c3401..06dc4d6551c 100644
--- a/sys/netinet/igmp.c
+++ b/sys/netinet/igmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: igmp.c,v 1.76 2020/08/17 16:25:34 gnezdo Exp $ */
+/* $OpenBSD: igmp.c,v 1.77 2021/12/15 15:58:01 bluhm Exp $ */
/* $NetBSD: igmp.c,v 1.15 1996/02/13 23:41:25 christos Exp $ */
/*
@@ -117,11 +117,7 @@ igmp_init(void)
LIST_INIT(&rti_head);
igmpcounters = counters_alloc(igps_ncounters);
- router_alert = m_get(M_DONTWAIT, MT_DATA);
- if (router_alert == NULL) {
- printf("%s: no mbuf\n", __func__);
- return;
- }
+ router_alert = m_get(M_WAIT, MT_DATA);
/*
* Construct a Router Alert option (RAO) to use in report
@@ -142,7 +138,6 @@ igmp_init(void)
router_alert->m_len = sizeof(ra->ipopt_dst) + ra->ipopt_list[1];
}
-/* Return -1 for error. */
int
rti_fill(struct in_multi *inm)
{
@@ -158,9 +153,7 @@ rti_fill(struct in_multi *inm)
}
}
- rti = malloc(sizeof(*rti), M_MRTABLE, M_NOWAIT);
- if (rti == NULL)
- return (-1);
+ rti = malloc(sizeof(*rti), M_MRTABLE, M_WAITOK);
rti->rti_ifidx = inm->inm_ifidx;
rti->rti_type = IGMP_v2_ROUTER;
LIST_INSERT_HEAD(&rti_head, rti, rti_list);
@@ -501,9 +494,7 @@ igmp_joingroup(struct in_multi *inm)
if (!IN_LOCAL_GROUP(inm->inm_addr.s_addr) &&
ifp && (ifp->if_flags & IFF_LOOPBACK) == 0) {
- if ((i = rti_fill(inm)) == -1)
- goto out;
-
+ i = rti_fill(inm);
igmp_sendpkt(ifp, inm, i, 0);
inm->inm_state = IGMP_DELAYING_MEMBER;
inm->inm_timer = IGMP_RANDOM_DELAY(
@@ -512,7 +503,6 @@ igmp_joingroup(struct in_multi *inm)
} else
inm->inm_timer = 0;
-out:
if_put(ifp);
}