* [PATCH] md/raid1: Prevent excessively large memory allocations
@ 2026-10-28 15:27 Gowtham S Bhushan
2026-10-30 4:40 ` [PATCH v2] md/raid1: reject out-of-range raid_disks in setup_conf() Gowtham S Bhushan
0 siblings, 1 reply; 2+ messages in thread
From: Gowtham S Bhushan @ 2026-10-28 15:27 UTC (permalink / raw)
To: song, yukuai
Cc: magiclinan, xiao, linux-raid, linux-kernel,
syzbot+fc26c366038b54261e53, Gowtham S Bhushan,
syzbot+75f49ec552cc74d9d69b, stable, syzkaller-bugs
Validate mddev->raid_disks before memory allocation to prevent integer
wrap-around or allocating an unreasonably large chunk of memory that
exceeds KMALLOC_MAX_SIZE boundaries.
Reported-by: syzbot+75f49ec552cc74d9d69b@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=75f49ec552cc74d9d69b
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Tested-by: syzbot+75f49ec552cc74d9d69b@syzkaller.appspotmail.com
Cc: stable@vger.kernel.org
Cc: syzkaller-bugs@googlegroups.com
Signed-off-by: Gowtham S Bhushan <gowtham398gs@gmail.com>
---
drivers/md/raid1.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index f0646fb24371..88038d535727 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -3050,6 +3050,16 @@ static struct r1conf *setup_conf(struct mddev *mddev)
struct md_rdev *rdev;
size_t r1bio_size;
int err = -ENOMEM;
+ size_t calculated_size;
+
+ /* prevent baseline integer wrap-around anomalies first*/
+ /* Safely calculate size; overflows automatically saturate to SIZE_MAX */
+
+ calculated_size = size_add(sizeof(struct r1conf),
+ size_mul(mddev->raid_disks, sizeof(struct r1bio)));
+
+ if (mddev->raid_disks <= 0 || calculated_size >= KMALLOC_MAX_SIZE)
+ return ERR_PTR(-EINVAL);
conf = kzalloc_obj(struct r1conf);
if (!conf)
--
2.56.0
^ permalink raw reply [flat|nested] 2+ messages in thread* [PATCH v2] md/raid1: reject out-of-range raid_disks in setup_conf()
2026-10-28 15:27 [PATCH] md/raid1: Prevent excessively large memory allocations Gowtham S Bhushan
@ 2026-10-30 4:40 ` Gowtham S Bhushan
0 siblings, 0 replies; 2+ messages in thread
From: Gowtham S Bhushan @ 2026-10-30 4:40 UTC (permalink / raw)
To: song, yukuai
Cc: magiclinan, xiao, linux-raid, linux-kernel,
syzbot+fc26c366038b54261e53, Gowtham S Bhushan,
syzbot+75f49ec552cc74d9d69b
mddev->raid_disks can be set from user space with SET_ARRAY_INFO and
is not bounded before RUN_ARRAY reaches raid1_run(). With a very large
value, setup_conf() asks the allocator for more than KMALLOC_MAX_SIZE
when allocating conf->mirrors, and the allocator warns:
WARNING: mm/slub.c:5459 at ___kmalloc_large_node
setup_conf+0x15d/0x700
raid1_run+0x109/0x250
md_run+0x6c3/0xec0
do_md_run+0x27/0x3b0
md_ioctl+0x163f/0x1ca0
The array fails to start, but machines running with panic_on_warn
crash and syzbot keeps reporting it.
Fail early instead. Version 1.x metadata can describe at most 1920
devices, so use that as the upper bound, and test the sign before the
value is used. At that limit the allocations that scale with
raid_disks (conf->mirrors, the r1bio mempool element and the resync
buffers) stay well below KMALLOC_MAX_SIZE.
Reported-by: syzbot+75f49ec552cc74d9d69b@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=75f49ec552cc74d9d69b
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Gowtham S Bhushan <gowtham398gs@gmail.com>
---
drivers/md/raid1.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index f0646fb24371..1cfe983167de 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -48,6 +48,13 @@ static void allow_barrier(struct r1conf *conf, sector_t sector_nr);
static void lower_barrier(struct r1conf *conf, sector_t sector_nr);
static void raid1_free(struct mddev *mddev, void *priv);
+/*
+ * Version 1.x md metadata keeps a 256-byte header and then 2 bytes per
+ * device in a 4096-byte block, so no array described by it can have more
+ * devices than this. Arrays created through the ioctl alone have no
+ * on-disk limit, so apply the same cap to them.
+ */
+#define RAID1_MAX_DISKS ((4096 - 256) / 2)
#define RAID_1_10_NAME "raid1"
#include "raid1-10.c"
@@ -3051,6 +3058,11 @@ static struct r1conf *setup_conf(struct mddev *mddev)
size_t r1bio_size;
int err = -ENOMEM;
+ /* raid_disks comes from user space and sizes the allocations below */
+
+ if (mddev->raid_disks <= 0 || mddev->raid_disks > RAID1_MAX_DISKS)
+ return ERR_PTR(-EINVAL);
+
conf = kzalloc_obj(struct r1conf);
if (!conf)
goto abort;
--
2.56.0
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-30 4:40 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-28 15:27 [PATCH] md/raid1: Prevent excessively large memory allocations Gowtham S Bhushan
2026-10-30 4:40 ` [PATCH v2] md/raid1: reject out-of-range raid_disks in setup_conf() Gowtham S Bhushan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®