mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] btrfs: Avoid potential out-of-bounds in btrfs_encode_fh()
@ 2025-09-08 12:49 Anderson Nascimento
  2025-09-09 22:45 ` David Sterba
  0 siblings, 1 reply; 6+ messages in thread
From: Anderson Nascimento @ 2025-09-08 12:49 UTC (permalink / raw)
  To: clm, josef, dsterba, linux-btrfs, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1414 bytes --]

Hello all,

The function btrfs_encode_fh() does not properly account for the three 
cases it handles.

Before writing to the file handle (fh), the function only returns to the 
user BTRFS_FID_SIZE_NON_CONNECTABLE (5 dwords, 20 bytes) or 
BTRFS_FID_SIZE_CONNECTABLE (8 dwords, 32 bytes).

However, when a parent exists and the root ID of the parent and the 
inode are different, the function writes BTRFS_FID_SIZE_CONNECTABLE_ROOT 
(10 dwords, 40 bytes).

If *max_len is not large enough, this write goes out of bounds because 
BTRFS_FID_SIZE_CONNECTABLE_ROOT is greater than 
BTRFS_FID_SIZE_CONNECTABLE originally returned.

This results in an 8-byte out-of-bounds write at 
fid->parent_root_objectid = parent_root_id.

A previous attempt to fix this issue was made but was lost.

https://lore.kernel.org/all/4CADAEEC020000780001B32C@vpn.id2.novell.com/

Although this issue does not seem to be easily triggerable, it is a 
potential memory corruption bug that should be fixed. This patch 
resolves the issue by ensuring the function returns the appropriate size 
for all three cases and validates that *max_len is large enough before 
writing any data.

Tested on v6.17-rc4.

Fixes: be6e8dc0ba84 ("NFS support for btrfs - v3")
Signed-off-by: Anderson Nascimento <anderson@allelesecurity.com>
---

fs/btrfs/export.c | 7 ++++++-
  1 file changed, 6 insertions(+), 1 deletion(-)

[-- Attachment #2: btrfs_out_of_bounds_in_btrfs_encode_fh.patch --]
[-- Type: text/x-patch, Size: 1054 bytes --]

diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c
index 7fc8a3200b40..086a97c2aa69 100644
--- a/fs/btrfs/export.c
+++ b/fs/btrfs/export.c
@@ -23,7 +23,10 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
 	int type;
 
 	if (parent && (len < BTRFS_FID_SIZE_CONNECTABLE)) {
-		*max_len = BTRFS_FID_SIZE_CONNECTABLE;
+		if(btrfs_root_id(BTRFS_I(inode)->root) != btrfs_root_id(BTRFS_I(parent)->root))
+			*max_len = BTRFS_FID_SIZE_CONNECTABLE_ROOT;
+		else
+			*max_len = BTRFS_FID_SIZE_CONNECTABLE;
 		return FILEID_INVALID;
 	} else if (len < BTRFS_FID_SIZE_NON_CONNECTABLE) {
 		*max_len = BTRFS_FID_SIZE_NON_CONNECTABLE;
@@ -45,6 +48,8 @@ static int btrfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
 		parent_root_id = btrfs_root_id(BTRFS_I(parent)->root);
 
 		if (parent_root_id != fid->root_objectid) {
+			if(*max_len < BTRFS_FID_SIZE_CONNECTABLE_ROOT)
+				return FILEID_INVALID;
 			fid->parent_root_objectid = parent_root_id;
 			len = BTRFS_FID_SIZE_CONNECTABLE_ROOT;
 			type = FILEID_BTRFS_WITH_PARENT_ROOT;

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] btrfs: Avoid potential out-of-bounds in btrfs_encode_fh()
  2025-09-08 12:49 [PATCH] btrfs: Avoid potential out-of-bounds in btrfs_encode_fh() Anderson Nascimento
@ 2025-09-09 22:45 ` David Sterba
  2025-09-09 23:39   ` Anderson Nascimento
  2025-09-23 14:37   ` Anderson Nascimento
  0 siblings, 2 replies; 6+ messages in thread
From: David Sterba @ 2025-09-09 22:45 UTC (permalink / raw)
  To: Anderson Nascimento; +Cc: clm, josef, dsterba, linux-btrfs, linux-kernel

On Mon, Sep 08, 2025 at 09:49:02AM -0300, Anderson Nascimento wrote:
> Hello all,
> 
> The function btrfs_encode_fh() does not properly account for the three 
> cases it handles.
> 
> Before writing to the file handle (fh), the function only returns to the 
> user BTRFS_FID_SIZE_NON_CONNECTABLE (5 dwords, 20 bytes) or 
> BTRFS_FID_SIZE_CONNECTABLE (8 dwords, 32 bytes).
> 
> However, when a parent exists and the root ID of the parent and the 
> inode are different, the function writes BTRFS_FID_SIZE_CONNECTABLE_ROOT 
> (10 dwords, 40 bytes).
> 
> If *max_len is not large enough, this write goes out of bounds because 
> BTRFS_FID_SIZE_CONNECTABLE_ROOT is greater than 
> BTRFS_FID_SIZE_CONNECTABLE originally returned.
> 
> This results in an 8-byte out-of-bounds write at 
> fid->parent_root_objectid = parent_root_id.
> 
> A previous attempt to fix this issue was made but was lost.
> 
> https://lore.kernel.org/all/4CADAEEC020000780001B32C@vpn.id2.novell.com/
> 
> Although this issue does not seem to be easily triggerable, it is a 
> potential memory corruption bug that should be fixed. This patch 
> resolves the issue by ensuring the function returns the appropriate size 
> for all three cases and validates that *max_len is large enough before 
> writing any data.
> 
> Tested on v6.17-rc4.
> 
> Fixes: be6e8dc0ba84 ("NFS support for btrfs - v3")
> Signed-off-by: Anderson Nascimento <anderson@allelesecurity.com>

Thanks for finding the problem and the fix. It's 17 years old though the
other patch was sent about 2 years after btrfs merge to linux kernel.
I'll add it to for-next, with the minor whitespace issues fixed.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] btrfs: Avoid potential out-of-bounds in btrfs_encode_fh()
  2025-09-09 22:45 ` David Sterba
@ 2025-09-09 23:39   ` Anderson Nascimento
  2025-09-23 14:37   ` Anderson Nascimento
  1 sibling, 0 replies; 6+ messages in thread
From: Anderson Nascimento @ 2025-09-09 23:39 UTC (permalink / raw)
  To: dsterba; +Cc: clm, josef, dsterba, linux-btrfs, linux-kernel

Thank you!

On Tue, Sep 9, 2025 at 7:45 PM David Sterba <dsterba@suse.cz> wrote:
>
> On Mon, Sep 08, 2025 at 09:49:02AM -0300, Anderson Nascimento wrote:
> > Hello all,
> >
> > The function btrfs_encode_fh() does not properly account for the three
> > cases it handles.
> >
> > Before writing to the file handle (fh), the function only returns to the
> > user BTRFS_FID_SIZE_NON_CONNECTABLE (5 dwords, 20 bytes) or
> > BTRFS_FID_SIZE_CONNECTABLE (8 dwords, 32 bytes).
> >
> > However, when a parent exists and the root ID of the parent and the
> > inode are different, the function writes BTRFS_FID_SIZE_CONNECTABLE_ROOT
> > (10 dwords, 40 bytes).
> >
> > If *max_len is not large enough, this write goes out of bounds because
> > BTRFS_FID_SIZE_CONNECTABLE_ROOT is greater than
> > BTRFS_FID_SIZE_CONNECTABLE originally returned.
> >
> > This results in an 8-byte out-of-bounds write at
> > fid->parent_root_objectid = parent_root_id.
> >
> > A previous attempt to fix this issue was made but was lost.
> >
> > https://lore.kernel.org/all/4CADAEEC020000780001B32C@vpn.id2.novell.com/
> >
> > Although this issue does not seem to be easily triggerable, it is a
> > potential memory corruption bug that should be fixed. This patch
> > resolves the issue by ensuring the function returns the appropriate size
> > for all three cases and validates that *max_len is large enough before
> > writing any data.
> >
> > Tested on v6.17-rc4.
> >
> > Fixes: be6e8dc0ba84 ("NFS support for btrfs - v3")
> > Signed-off-by: Anderson Nascimento <anderson@allelesecurity.com>
>
> Thanks for finding the problem and the fix. It's 17 years old though the
> other patch was sent about 2 years after btrfs merge to linux kernel.
> I'll add it to for-next, with the minor whitespace issues fixed.



-- 
Anderson Nascimento
Allele Security Intelligence
https://www.allelesecurity.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] btrfs: Avoid potential out-of-bounds in btrfs_encode_fh()
  2025-09-09 22:45 ` David Sterba
  2025-09-09 23:39   ` Anderson Nascimento
@ 2025-09-23 14:37   ` Anderson Nascimento
  2025-09-23 15:11     ` David Sterba
  1 sibling, 1 reply; 6+ messages in thread
From: Anderson Nascimento @ 2025-09-23 14:37 UTC (permalink / raw)
  To: dsterba; +Cc: clm, josef, dsterba, linux-btrfs, linux-kernel

On Tue, Sep 9, 2025 at 7:45 PM David Sterba <dsterba@suse.cz> wrote:
>
> On Mon, Sep 08, 2025 at 09:49:02AM -0300, Anderson Nascimento wrote:
> > Hello all,
> >
> > The function btrfs_encode_fh() does not properly account for the three
> > cases it handles.
> >
> > Before writing to the file handle (fh), the function only returns to the
> > user BTRFS_FID_SIZE_NON_CONNECTABLE (5 dwords, 20 bytes) or
> > BTRFS_FID_SIZE_CONNECTABLE (8 dwords, 32 bytes).
> >
> > However, when a parent exists and the root ID of the parent and the
> > inode are different, the function writes BTRFS_FID_SIZE_CONNECTABLE_ROOT
> > (10 dwords, 40 bytes).
> >
> > If *max_len is not large enough, this write goes out of bounds because
> > BTRFS_FID_SIZE_CONNECTABLE_ROOT is greater than
> > BTRFS_FID_SIZE_CONNECTABLE originally returned.
> >
> > This results in an 8-byte out-of-bounds write at
> > fid->parent_root_objectid = parent_root_id.
> >
> > A previous attempt to fix this issue was made but was lost.
> >
> > https://lore.kernel.org/all/4CADAEEC020000780001B32C@vpn.id2.novell.com/
> >
> > Although this issue does not seem to be easily triggerable, it is a
> > potential memory corruption bug that should be fixed. This patch
> > resolves the issue by ensuring the function returns the appropriate size
> > for all three cases and validates that *max_len is large enough before
> > writing any data.
> >
> > Tested on v6.17-rc4.
> >
> > Fixes: be6e8dc0ba84 ("NFS support for btrfs - v3")
> > Signed-off-by: Anderson Nascimento <anderson@allelesecurity.com>
>
> Thanks for finding the problem and the fix. It's 17 years old though the
> other patch was sent about 2 years after btrfs merge to linux kernel.
> I'll add it to for-next, with the minor whitespace issues fixed.

David, has it been queued somewhere? I don't see it in any of your branches.

-- 
Anderson Nascimento
Allele Security Intelligence
https://www.allelesecurity.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] btrfs: Avoid potential out-of-bounds in btrfs_encode_fh()
  2025-09-23 14:37   ` Anderson Nascimento
@ 2025-09-23 15:11     ` David Sterba
  2025-09-23 15:55       ` Anderson Nascimento
  0 siblings, 1 reply; 6+ messages in thread
From: David Sterba @ 2025-09-23 15:11 UTC (permalink / raw)
  To: Anderson Nascimento; +Cc: clm, josef, dsterba, linux-btrfs, linux-kernel

On Tue, Sep 23, 2025 at 11:37:33AM -0300, Anderson Nascimento wrote:
> On Tue, Sep 9, 2025 at 7:45 PM David Sterba <dsterba@suse.cz> wrote:
> >
> > On Mon, Sep 08, 2025 at 09:49:02AM -0300, Anderson Nascimento wrote:
> > > Hello all,
> > >
> > > The function btrfs_encode_fh() does not properly account for the three
> > > cases it handles.
> > >
> > > Before writing to the file handle (fh), the function only returns to the
> > > user BTRFS_FID_SIZE_NON_CONNECTABLE (5 dwords, 20 bytes) or
> > > BTRFS_FID_SIZE_CONNECTABLE (8 dwords, 32 bytes).
> > >
> > > However, when a parent exists and the root ID of the parent and the
> > > inode are different, the function writes BTRFS_FID_SIZE_CONNECTABLE_ROOT
> > > (10 dwords, 40 bytes).
> > >
> > > If *max_len is not large enough, this write goes out of bounds because
> > > BTRFS_FID_SIZE_CONNECTABLE_ROOT is greater than
> > > BTRFS_FID_SIZE_CONNECTABLE originally returned.
> > >
> > > This results in an 8-byte out-of-bounds write at
> > > fid->parent_root_objectid = parent_root_id.
> > >
> > > A previous attempt to fix this issue was made but was lost.
> > >
> > > https://lore.kernel.org/all/4CADAEEC020000780001B32C@vpn.id2.novell.com/
> > >
> > > Although this issue does not seem to be easily triggerable, it is a
> > > potential memory corruption bug that should be fixed. This patch
> > > resolves the issue by ensuring the function returns the appropriate size
> > > for all three cases and validates that *max_len is large enough before
> > > writing any data.
> > >
> > > Tested on v6.17-rc4.
> > >
> > > Fixes: be6e8dc0ba84 ("NFS support for btrfs - v3")
> > > Signed-off-by: Anderson Nascimento <anderson@allelesecurity.com>
> >
> > Thanks for finding the problem and the fix. It's 17 years old though the
> > other patch was sent about 2 years after btrfs merge to linux kernel.
> > I'll add it to for-next, with the minor whitespace issues fixed.
> 
> David, has it been queued somewhere? I don't see it in any of your branches.

That's strange, I thought I'd applied it the same day but the patch is
nowhere to be found. I'll add it to for-next again, sorry.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] btrfs: Avoid potential out-of-bounds in btrfs_encode_fh()
  2025-09-23 15:11     ` David Sterba
@ 2025-09-23 15:55       ` Anderson Nascimento
  0 siblings, 0 replies; 6+ messages in thread
From: Anderson Nascimento @ 2025-09-23 15:55 UTC (permalink / raw)
  To: dsterba; +Cc: clm, josef, dsterba, linux-btrfs, linux-kernel

On Tue, Sep 23, 2025 at 12:11 PM David Sterba <dsterba@suse.cz> wrote:
>
> On Tue, Sep 23, 2025 at 11:37:33AM -0300, Anderson Nascimento wrote:
> > On Tue, Sep 9, 2025 at 7:45 PM David Sterba <dsterba@suse.cz> wrote:
> > >
> > > On Mon, Sep 08, 2025 at 09:49:02AM -0300, Anderson Nascimento wrote:
> > > > Hello all,
> > > >
> > > > The function btrfs_encode_fh() does not properly account for the three
> > > > cases it handles.
> > > >
> > > > Before writing to the file handle (fh), the function only returns to the
> > > > user BTRFS_FID_SIZE_NON_CONNECTABLE (5 dwords, 20 bytes) or
> > > > BTRFS_FID_SIZE_CONNECTABLE (8 dwords, 32 bytes).
> > > >
> > > > However, when a parent exists and the root ID of the parent and the
> > > > inode are different, the function writes BTRFS_FID_SIZE_CONNECTABLE_ROOT
> > > > (10 dwords, 40 bytes).
> > > >
> > > > If *max_len is not large enough, this write goes out of bounds because
> > > > BTRFS_FID_SIZE_CONNECTABLE_ROOT is greater than
> > > > BTRFS_FID_SIZE_CONNECTABLE originally returned.
> > > >
> > > > This results in an 8-byte out-of-bounds write at
> > > > fid->parent_root_objectid = parent_root_id.
> > > >
> > > > A previous attempt to fix this issue was made but was lost.
> > > >
> > > > https://lore.kernel.org/all/4CADAEEC020000780001B32C@vpn.id2.novell.com/
> > > >
> > > > Although this issue does not seem to be easily triggerable, it is a
> > > > potential memory corruption bug that should be fixed. This patch
> > > > resolves the issue by ensuring the function returns the appropriate size
> > > > for all three cases and validates that *max_len is large enough before
> > > > writing any data.
> > > >
> > > > Tested on v6.17-rc4.
> > > >
> > > > Fixes: be6e8dc0ba84 ("NFS support for btrfs - v3")
> > > > Signed-off-by: Anderson Nascimento <anderson@allelesecurity.com>
> > >
> > > Thanks for finding the problem and the fix. It's 17 years old though the
> > > other patch was sent about 2 years after btrfs merge to linux kernel.
> > > I'll add it to for-next, with the minor whitespace issues fixed.
> >
> > David, has it been queued somewhere? I don't see it in any of your branches.
>
> That's strange, I thought I'd applied it the same day but the patch is
> nowhere to be found. I'll add it to for-next again, sorry.

No worries, thank you very much.

-- 
Anderson Nascimento
Allele Security Intelligence
https://www.allelesecurity.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-09-23 15:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-09-08 12:49 [PATCH] btrfs: Avoid potential out-of-bounds in btrfs_encode_fh() Anderson Nascimento
2025-09-09 22:45 ` David Sterba
2025-09-09 23:39   ` Anderson Nascimento
2025-09-23 14:37   ` Anderson Nascimento
2025-09-23 15:11     ` David Sterba
2025-09-23 15:55       ` Anderson Nascimento

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®