[PATCH] adfs: validate nzones in adfs_read_map()

Greg Kroah-Hartman posted 1 patch 2 weeks ago
fs/adfs/map.c | 4 ++++
1 file changed, 4 insertions(+)
[PATCH] adfs: validate nzones in adfs_read_map()
Posted by Greg Kroah-Hartman 2 weeks ago
From: Bae Yeonju <iwasbaeyz@gmail.com>

adfs_read_map() reads the zone count from the on-disk disc record
without validation:

  nzones = dr->nzones | dr->nzones_high << 8;

When nzones is 0, the subsequent kmalloc_array(0, ...) returns
ZERO_SIZE_PTR (0x10), and adfs_map_layout() writes to dm[-1],
causing an out-of-bounds write before the allocated buffer.

This can be triggered by mounting a crafted ADFS filesystem image
with nzones set to 0 in the disc record. It leads to kernel heap
corruption and a NULL pointer dereference during mount.

Add a check to reject disc records with nzones == 0 before the
allocation.

Found by syzkaller.

Fixes: f6f14a0d71b0 ("fs/adfs: map: move map-specific sb initialisation to map.c")
Cc: stable <stable@kernel.org>
Cc: Kees Cook <kees@kernel.org>
Cc: Bae Yeonju <iwasbaeyz@gmail.com>
Cc: Russell King <rmk+kernel@armlinux.org.uk>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Bae Yeonju <iwasbaeyz@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/adfs/map.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/adfs/map.c b/fs/adfs/map.c
index 9d535a2ca2d1..5d671e7b4663 100644
--- a/fs/adfs/map.c
+++ b/fs/adfs/map.c
@@ -361,6 +361,10 @@ struct adfs_discmap *adfs_read_map(struct super_block *sb, struct adfs_discrecor
 	int ret;
 
 	nzones    = dr->nzones | dr->nzones_high << 8;
+	if (nzones == 0) {
+		adfs_error(sb, "invalid zone count");
+		return ERR_PTR(-EINVAL);
+	}
 	zone_size = (8 << dr->log2secsize) - le16_to_cpu(dr->zone_spare);
 
 	asb->s_idlen = dr->idlen;
-- 
2.53.0
Re: [PATCH] adfs: validate nzones in adfs_read_map()
Posted by Russell King (Oracle) 2 weeks ago
On Fri, Mar 20, 2026 at 03:23:56PM +0100, Greg Kroah-Hartman wrote:
> From: Bae Yeonju <iwasbaeyz@gmail.com>
> 
> adfs_read_map() reads the zone count from the on-disk disc record
> without validation:
> 
>   nzones = dr->nzones | dr->nzones_high << 8;
> 
> When nzones is 0, the subsequent kmalloc_array(0, ...) returns
> ZERO_SIZE_PTR (0x10), and adfs_map_layout() writes to dm[-1],
> causing an out-of-bounds write before the allocated buffer.
> 
> This can be triggered by mounting a crafted ADFS filesystem image
> with nzones set to 0 in the disc record. It leads to kernel heap
> corruption and a NULL pointer dereference during mount.
> 
> Add a check to reject disc records with nzones == 0 before the
> allocation.
> 
> Found by syzkaller.

I didn't see this patch.

This is a silly place to put the check - it should be done while
validating the disc record, in adfs_validate_bblk(), not when trying
to use it.

Note that adfs_validate_dr0() already validates the number of zones.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
Re: [PATCH] adfs: validate nzones in adfs_read_map()
Posted by Greg Kroah-Hartman 2 weeks ago
On Fri, Mar 20, 2026 at 02:37:15PM +0000, Russell King (Oracle) wrote:
> On Fri, Mar 20, 2026 at 03:23:56PM +0100, Greg Kroah-Hartman wrote:
> > From: Bae Yeonju <iwasbaeyz@gmail.com>
> > 
> > adfs_read_map() reads the zone count from the on-disk disc record
> > without validation:
> > 
> >   nzones = dr->nzones | dr->nzones_high << 8;
> > 
> > When nzones is 0, the subsequent kmalloc_array(0, ...) returns
> > ZERO_SIZE_PTR (0x10), and adfs_map_layout() writes to dm[-1],
> > causing an out-of-bounds write before the allocated buffer.
> > 
> > This can be triggered by mounting a crafted ADFS filesystem image
> > with nzones set to 0 in the disc record. It leads to kernel heap
> > corruption and a NULL pointer dereference during mount.
> > 
> > Add a check to reject disc records with nzones == 0 before the
> > allocation.
> > 
> > Found by syzkaller.
> 
> I didn't see this patch.

This is the first time it has been sent in public.

> This is a silly place to put the check - it should be done while
> validating the disc record, in adfs_validate_bblk(), not when trying
> to use it.
> 
> Note that adfs_validate_dr0() already validates the number of zones.

But then why is this check also needed?  I'm all for moving it
elsewhere, Bae has the reproducer, they can check if moving it fixes
their issue or not.

thanks,

greg k-h
Re: [PATCH] adfs: validate nzones in adfs_read_map()
Posted by Russell King (Oracle) 2 weeks ago
On Fri, Mar 20, 2026 at 04:05:03PM +0100, Greg Kroah-Hartman wrote:
> But then why is this check also needed?  I'm all for moving it
> elsewhere, Bae has the reproducer, they can check if moving it fixes
> their issue or not.

There are two variants of the disc format.

adfs_validate_bblk() which is used for hard disc formats where the
number of zones is greater than zero, and ADFS F format on floppy
disks which should have four zones.) This doesn't validate the
number of zones, but it should - and this is where it should be
added, not in the map reading code.

The other uses adfs_validate_dr0(), which is for the ADFS E floppy
format images. This already validates that the number of zones is
equal to one.

Reference:
https://www.riscosopen.org/wiki/documentation/show/FileCore%20Overview#laylogic

Only "new map" is supported by adfs under Linux.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
Re: [PATCH] adfs: validate nzones in adfs_read_map()
Posted by paeyz 2 weeks ago
From: Bae Yeonju <iwasbaeyz@gmail.com>

Hi,

I tested moving the nzones validation to adfs_validate_bblk() on
6.12.36 with KASAN enabled.

With this change, a crafted image with nzones=0 is rejected during
validation:

  ADFS-fs (loop0): error: can't find an ADFS filesystem on dev loop0.

mount() returns -EINVAL, and no crash or KASAN report is observed.

So the issue can be prevented by validating nzones earlier in the
validation path.

Tested-by: Bae Yeonju <iwasbaeyz@gmail.com>
Re: [PATCH] adfs: validate nzones in adfs_read_map()
Posted by Greg KH 2 weeks ago
On Sat, Mar 21, 2026 at 12:21:31AM +0900, paeyz wrote:
> From: Bae Yeonju <iwasbaeyz@gmail.com>
> 
> Hi,
> 
> I tested moving the nzones validation to adfs_validate_bblk() on
> 6.12.36 with KASAN enabled.
> 
> With this change, a crafted image with nzones=0 is rejected during
> validation:
> 
>   ADFS-fs (loop0): error: can't find an ADFS filesystem on dev loop0.
> 
> mount() returns -EINVAL, and no crash or KASAN report is observed.
> 
> So the issue can be prevented by validating nzones earlier in the
> validation path.
> 
> Tested-by: Bae Yeonju <iwasbaeyz@gmail.com>

Great, can you rework your patch to move the check to that location and
send it?

thanks,

greg k-h
Re: [PATCH] adfs: validate nzones in adfs_read_map()
Posted by Russell King (Oracle) 2 weeks ago
On Fri, Mar 20, 2026 at 04:40:57PM +0100, Greg KH wrote:
> On Sat, Mar 21, 2026 at 12:21:31AM +0900, paeyz wrote:
> > From: Bae Yeonju <iwasbaeyz@gmail.com>
> > 
> > Hi,
> > 
> > I tested moving the nzones validation to adfs_validate_bblk() on
> > 6.12.36 with KASAN enabled.
> > 
> > With this change, a crafted image with nzones=0 is rejected during
> > validation:
> > 
> >   ADFS-fs (loop0): error: can't find an ADFS filesystem on dev loop0.
> > 
> > mount() returns -EINVAL, and no crash or KASAN report is observed.
> > 
> > So the issue can be prevented by validating nzones earlier in the
> > validation path.
> > 
> > Tested-by: Bae Yeonju <iwasbaeyz@gmail.com>
> 
> Great, can you rework your patch to move the check to that location and
> send it?

... great, giving me no chance to reply to your previous email...

In netdev land, we have a rule: wait 24 hours between posting updates,
so that discussion has a chance of completing. I suggest that would
have been good here.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
[PATCH v2] adfs: validate nzones in adfs_validate_bblk()
Posted by paeyz 2 weeks ago
From: Bae Yeonju <iwasbaeyz@gmail.com>

Reject ADFS disc records with a zero zone count during boot block
validation, before the disc record is used.

When nzones is 0, adfs_read_map() passes it to kmalloc_array(0, ...)
which returns ZERO_SIZE_PTR, and adfs_map_layout() then writes to
dm[-1], causing an out-of-bounds write before the allocated buffer.

adfs_validate_dr0() already rejects nzones != 1 for old-format
images.  Add the equivalent check to adfs_validate_bblk() for
new-format images so that a crafted image with nzones == 0 is
rejected at probe time.

Found by syzkaller.

Fixes: f6f14a0d71b0 ("fs/adfs: map: move map-specific sb initialisation to map.c")
Tested-by: Bae Yeonju <iwasbaeyz@gmail.com>
Signed-off-by: Bae Yeonju <iwasbaeyz@gmail.com>
---
 fs/adfs/super.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 4d3015e3a..b5522b862 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -343,6 +343,9 @@ static int adfs_validate_bblk(struct super_block *sb, struct buffer_head *bh,
 	if (adfs_checkdiscrecord(dr))
 		return -EILSEQ;

+	if ((dr->nzones | dr->nzones_high << 8) == 0)
+		return -EILSEQ;
+
 	*drp = dr;
 	return 0;
 }
--
2.43.0
Re: [PATCH v2] adfs: validate nzones in adfs_validate_bblk()
Posted by Greg KH 2 weeks ago
On Sat, Mar 21, 2026 at 12:52:13AM +0900, paeyz wrote:
> From: Bae Yeonju <iwasbaeyz@gmail.com>
> 
> Reject ADFS disc records with a zero zone count during boot block
> validation, before the disc record is used.
> 
> When nzones is 0, adfs_read_map() passes it to kmalloc_array(0, ...)
> which returns ZERO_SIZE_PTR, and adfs_map_layout() then writes to
> dm[-1], causing an out-of-bounds write before the allocated buffer.
> 
> adfs_validate_dr0() already rejects nzones != 1 for old-format
> images.  Add the equivalent check to adfs_validate_bblk() for
> new-format images so that a crafted image with nzones == 0 is
> rejected at probe time.
> 
> Found by syzkaller.
> 
> Fixes: f6f14a0d71b0 ("fs/adfs: map: move map-specific sb initialisation to map.c")
> Tested-by: Bae Yeonju <iwasbaeyz@gmail.com>
> Signed-off-by: Bae Yeonju <iwasbaeyz@gmail.com>

Nit, no need for Tested-by if you sign off on the change :)

> ---
>  fs/adfs/super.c | 3 +++
>  1 file changed, 3 insertions(+)

The version info from what changed goes below the --- line.

Anyway, who takes adfs changes these days?  Russell do you?  There's no
MAINTAINERS entry that I can find.  If no one else, I can take it
through one of my trees.

thanks,

greg k-h
Re: [PATCH v2] adfs: validate nzones in adfs_validate_bblk()
Posted by Russell King (Oracle) 2 weeks ago
On Fri, Mar 20, 2026 at 05:04:07PM +0100, Greg KH wrote:
> On Sat, Mar 21, 2026 at 12:52:13AM +0900, paeyz wrote:
> > From: Bae Yeonju <iwasbaeyz@gmail.com>
> > 
> > Reject ADFS disc records with a zero zone count during boot block
> > validation, before the disc record is used.
> > 
> > When nzones is 0, adfs_read_map() passes it to kmalloc_array(0, ...)
> > which returns ZERO_SIZE_PTR, and adfs_map_layout() then writes to
> > dm[-1], causing an out-of-bounds write before the allocated buffer.
> > 
> > adfs_validate_dr0() already rejects nzones != 1 for old-format
> > images.  Add the equivalent check to adfs_validate_bblk() for
> > new-format images so that a crafted image with nzones == 0 is
> > rejected at probe time.
> > 
> > Found by syzkaller.
> > 
> > Fixes: f6f14a0d71b0 ("fs/adfs: map: move map-specific sb initialisation to map.c")
> > Tested-by: Bae Yeonju <iwasbaeyz@gmail.com>
> > Signed-off-by: Bae Yeonju <iwasbaeyz@gmail.com>
> 
> Nit, no need for Tested-by if you sign off on the change :)
> 
> > ---
> >  fs/adfs/super.c | 3 +++
> >  1 file changed, 3 insertions(+)
> 
> The version info from what changed goes below the --- line.
> 
> Anyway, who takes adfs changes these days?  Russell do you?  There's no
> MAINTAINERS entry that I can find.  If no one else, I can take it
> through one of my trees.

I have done, as I'm the author of this fs driver.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
Re: [PATCH v2] adfs: validate nzones in adfs_validate_bblk()
Posted by Greg KH 2 weeks ago
On Fri, Mar 20, 2026 at 04:08:26PM +0000, Russell King (Oracle) wrote:
> On Fri, Mar 20, 2026 at 05:04:07PM +0100, Greg KH wrote:
> > On Sat, Mar 21, 2026 at 12:52:13AM +0900, paeyz wrote:
> > > From: Bae Yeonju <iwasbaeyz@gmail.com>
> > > 
> > > Reject ADFS disc records with a zero zone count during boot block
> > > validation, before the disc record is used.
> > > 
> > > When nzones is 0, adfs_read_map() passes it to kmalloc_array(0, ...)
> > > which returns ZERO_SIZE_PTR, and adfs_map_layout() then writes to
> > > dm[-1], causing an out-of-bounds write before the allocated buffer.
> > > 
> > > adfs_validate_dr0() already rejects nzones != 1 for old-format
> > > images.  Add the equivalent check to adfs_validate_bblk() for
> > > new-format images so that a crafted image with nzones == 0 is
> > > rejected at probe time.
> > > 
> > > Found by syzkaller.
> > > 
> > > Fixes: f6f14a0d71b0 ("fs/adfs: map: move map-specific sb initialisation to map.c")
> > > Tested-by: Bae Yeonju <iwasbaeyz@gmail.com>
> > > Signed-off-by: Bae Yeonju <iwasbaeyz@gmail.com>
> > 
> > Nit, no need for Tested-by if you sign off on the change :)
> > 
> > > ---
> > >  fs/adfs/super.c | 3 +++
> > >  1 file changed, 3 insertions(+)
> > 
> > The version info from what changed goes below the --- line.
> > 
> > Anyway, who takes adfs changes these days?  Russell do you?  There's no
> > MAINTAINERS entry that I can find.  If no one else, I can take it
> > through one of my trees.
> 
> I have done, as I'm the author of this fs driver.

Great, thanks!

Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[PATCH v3] adfs: validate nzones in adfs_validate_bblk()
Posted by paeyz 2 weeks ago
From: Bae Yeonju <iwasbaeyz@gmail.com>

Reject ADFS disc records with a zero zone count during boot block
validation, before the disc record is used.

When nzones is 0, adfs_read_map() passes it to kmalloc_array(0, ...)
which returns ZERO_SIZE_PTR, and adfs_map_layout() then writes to
dm[-1], causing an out-of-bounds write before the allocated buffer.

adfs_validate_dr0() already rejects nzones != 1 for old-format
images.  Add the equivalent check to adfs_validate_bblk() for
new-format images so that a crafted image with nzones == 0 is
rejected at probe time.

Found by syzkaller.

Fixes: f6f14a0d71b0 ("fs/adfs: map: move map-specific sb initialisation to map.c")
Signed-off-by: Bae Yeonju <iwasbaeyz@gmail.com>
---
Changes in v3:
  - Drop redundant Tested-by

Changes in v2:
  - Move check from adfs_read_map() to adfs_validate_bblk() (Russell King)

 fs/adfs/super.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/adfs/super.c b/fs/adfs/super.c
index 4d3015e3a..b5522b862 100644
--- a/fs/adfs/super.c
+++ b/fs/adfs/super.c
@@ -343,6 +343,9 @@ static int adfs_validate_bblk(struct super_block *sb, struct buffer_head *bh,
 	if (adfs_checkdiscrecord(dr))
 		return -EILSEQ;

+	if ((dr->nzones | dr->nzones_high << 8) == 0)
+		return -EILSEQ;
+
 	*drp = dr;
 	return 0;
 }
--
2.43.0