summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2024-09-24 12:37:12 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2024-09-24 12:37:12 +0000
commit1b14f7978b262ae0c64d32e5dfaa9e61753e9471 (patch)
treefc942059352bc2e36a440dc0362b70901af9804d /sys/kern
parent06f7e7dc01c856d318c728644547a52ff9f5af1e (diff)
Fix sleeping race during malloc in sysctl hw.disknames.
When mallocarray(9) sleeps, disk_count can change, and diskstatslen gets inconsistent. This caused free(9) to panic. Reported-by: syzbot+36e1f3b306f721f90c72@syzkaller.appspotmail.com OK deraadt@ mpi@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_sysctl.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index e015b530563..c02866c4e95 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.446 2024/08/29 10:44:40 bluhm Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.447 2024/09/24 12:37:11 bluhm Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -2491,7 +2491,7 @@ sysctl_diskinit(int update, struct proc *p)
/* Run in a loop, disks may change while malloc sleeps. */
while (disk_change) {
- int tlen;
+ int tlen, count;
disk_change = 0;
@@ -2502,6 +2502,8 @@ sysctl_diskinit(int update, struct proc *p)
tlen += 18; /* label uid + separators */
}
tlen++;
+ /* disk_count may change when malloc sleeps */
+ count = disk_count;
/*
* The sysctl_disklock ensures that no other process can
@@ -2511,9 +2513,9 @@ sysctl_diskinit(int update, struct proc *p)
free(diskstats, M_SYSCTL, diskstatslen);
diskstats = NULL;
disknames = NULL;
- diskstats = mallocarray(disk_count, sizeof(struct diskstats),
+ diskstats = mallocarray(count, sizeof(struct diskstats),
M_SYSCTL, M_WAITOK|M_ZERO);
- diskstatslen = disk_count * sizeof(struct diskstats);
+ diskstatslen = count * sizeof(struct diskstats);
disknames = malloc(tlen, M_SYSCTL, M_WAITOK|M_ZERO);
disknameslen = tlen;
disknames[0] = '\0';