diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-09-24 12:37:12 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-09-24 12:37:12 +0000 |
commit | 1b14f7978b262ae0c64d32e5dfaa9e61753e9471 (patch) | |
tree | fc942059352bc2e36a440dc0362b70901af9804d /sys/kern | |
parent | 06f7e7dc01c856d318c728644547a52ff9f5af1e (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.c | 10 |
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'; |