public inbox for linux-ext4@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ext4: Fix possible NULL pointer dereference in ext4_group_desc_free()
@ 2026-03-16  8:20 Zqiang
  2026-03-16 15:49 ` Baokun Li
  0 siblings, 1 reply; 5+ messages in thread
From: Zqiang @ 2026-03-16  8:20 UTC (permalink / raw)
  To: tytso, adilger.kernel; +Cc: linux-ext4, linux-kernel, qiang.zhang

This can happen if the kvmalloc_objs() fails and sbi->s_group_desc pointer
is NULL in the ext4_group_desc_init(), and then the ext4_group_desc_free()
is called, leading to a NULL group_desc pointer dereference.

This commit therefore adds a NULL check for sbi->s_group_desc before
accessing its internal members.

Signed-off-by: Zqiang <qiang.zhang@linux.dev>
---
 fs/ext4/super.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 43f680c750ae..c4307dc04687 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1256,9 +1256,11 @@ static void ext4_group_desc_free(struct ext4_sb_info *sbi)
 
 	rcu_read_lock();
 	group_desc = rcu_dereference(sbi->s_group_desc);
-	for (i = 0; i < sbi->s_gdb_count; i++)
-		brelse(group_desc[i]);
-	kvfree(group_desc);
+	if (group_desc) {
+		for (i = 0; i < sbi->s_gdb_count; i++)
+			brelse(group_desc[i]);
+		kvfree(group_desc);
+	}
 	rcu_read_unlock();
 }
 
-- 
2.17.1


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

* Re: [PATCH] ext4: Fix possible NULL pointer dereference in ext4_group_desc_free()
  2026-03-16  8:20 [PATCH] ext4: Fix possible NULL pointer dereference in ext4_group_desc_free() Zqiang
@ 2026-03-16 15:49 ` Baokun Li
  2026-03-16 23:33   ` Zqiang
  0 siblings, 1 reply; 5+ messages in thread
From: Baokun Li @ 2026-03-16 15:49 UTC (permalink / raw)
  To: Zqiang; +Cc: linux-ext4, linux-kernel, tytso, adilger.kernel, libaokun


On 3/16/26 4:20 PM, Zqiang wrote:
> This can happen if the kvmalloc_objs() fails and sbi->s_group_desc pointer
> is NULL in the ext4_group_desc_init(), and then the ext4_group_desc_free()
> is called, leading to a NULL group_desc pointer dereference.
>
> This commit therefore adds a NULL check for sbi->s_group_desc before
> accessing its internal members.
>
> Signed-off-by: Zqiang <qiang.zhang@linux.dev>
> ---
>  fs/ext4/super.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index 43f680c750ae..c4307dc04687 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -1256,9 +1256,11 @@ static void ext4_group_desc_free(struct ext4_sb_info *sbi)
>  
>  	rcu_read_lock();
>  	group_desc = rcu_dereference(sbi->s_group_desc);
> -	for (i = 0; i < sbi->s_gdb_count; i++)

In ext4_group_desc_init(), s_gdb_count is only assigned after kvmalloc_array
allocation succeeds. Therefore, when kvmalloc_array fails, the
brelse(group_desc[i]) in ext4_group_desc_free() will not actually be
executed,
and thus this NULL pointer dereference issue will not be triggered.


Cheers,
Baokun

> -		brelse(group_desc[i]);
> -	kvfree(group_desc);
> +	if (group_desc) {
> +		for (i = 0; i < sbi->s_gdb_count; i++)
> +			brelse(group_desc[i]);
> +		kvfree(group_desc);
> +	}
>  	rcu_read_unlock();
>  }
>  

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

* Re: [PATCH] ext4: Fix possible NULL pointer dereference in ext4_group_desc_free()
  2026-03-16 15:49 ` Baokun Li
@ 2026-03-16 23:33   ` Zqiang
  2026-03-17  6:32     ` Baokun Li
  0 siblings, 1 reply; 5+ messages in thread
From: Zqiang @ 2026-03-16 23:33 UTC (permalink / raw)
  To: Baokun Li; +Cc: linux-ext4, linux-kernel, tytso, adilger.kernel, libaokun

> 
> On 3/16/26 4:20 PM, Zqiang wrote:
> 
> > 
> > This can happen if the kvmalloc_objs() fails and sbi->s_group_desc pointer
> >  is NULL in the ext4_group_desc_init(), and then the ext4_group_desc_free()
> >  is called, leading to a NULL group_desc pointer dereference.
> > 
> >  This commit therefore adds a NULL check for sbi->s_group_desc before
> >  accessing its internal members.
> > 
> >  Signed-off-by: Zqiang <qiang.zhang@linux.dev>
> >  ---
> >  fs/ext4/super.c | 8 +++++---
> >  1 file changed, 5 insertions(+), 3 deletions(-)
> > 
> >  diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> >  index 43f680c750ae..c4307dc04687 100644
> >  --- a/fs/ext4/super.c
> >  +++ b/fs/ext4/super.c
> >  @@ -1256,9 +1256,11 @@ static void ext4_group_desc_free(struct ext4_sb_info *sbi)
> >  
> >  rcu_read_lock();
> >  group_desc = rcu_dereference(sbi->s_group_desc);
> >  - for (i = 0; i < sbi->s_gdb_count; i++)
> > 
> In ext4_group_desc_init(), s_gdb_count is only assigned after kvmalloc_array
> allocation succeeds. Therefore, when kvmalloc_array fails, the
> brelse(group_desc[i]) in ext4_group_desc_free() will not actually be
> executed,
> and thus this NULL pointer dereference issue will not be triggered.


Thanks for replay, got it, sorry for make noise.

Just then, I find that warning may be trigger:

the kvfree() is called in RCU read critical section, if
the sbi->s_group_desc pointer comes from vmalloc(),
the vfree() is called to release it, but the might_sleep()
is called in the vfree(), this may be trigger warnings in
rcu_sleep_check() when the enable CONFIG_DEBUG_ATOMIC_SLEEP.

May be use rcu_access_pointer() to access sbi->s_group_desc
is enough.

Thanks
Zqiang


> 
> Cheers,
> Baokun
> 
> > 
> > - brelse(group_desc[i]);
> >  - kvfree(group_desc);
> >  + if (group_desc) {
> >  + for (i = 0; i < sbi->s_gdb_count; i++)
> >  + brelse(group_desc[i]);
> >  + kvfree(group_desc);
> >  + }
> >  rcu_read_unlock();
> >  }
> >
>

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

* Re: [PATCH] ext4: Fix possible NULL pointer dereference in ext4_group_desc_free()
  2026-03-16 23:33   ` Zqiang
@ 2026-03-17  6:32     ` Baokun Li
  2026-03-17 13:23       ` Zqiang
  0 siblings, 1 reply; 5+ messages in thread
From: Baokun Li @ 2026-03-17  6:32 UTC (permalink / raw)
  To: Zqiang; +Cc: linux-ext4, linux-kernel, tytso, adilger.kernel, libaokun


On 3/17/26 7:33 AM, Zqiang wrote:
>> On 3/16/26 4:20 PM, Zqiang wrote:
>>
>>> This can happen if the kvmalloc_objs() fails and sbi->s_group_desc pointer
>>>  is NULL in the ext4_group_desc_init(), and then the ext4_group_desc_free()
>>>  is called, leading to a NULL group_desc pointer dereference.
>>>
>>>  This commit therefore adds a NULL check for sbi->s_group_desc before
>>>  accessing its internal members.
>>>
>>>  Signed-off-by: Zqiang <qiang.zhang@linux.dev>
>>>  ---
>>>  fs/ext4/super.c | 8 +++++---
>>>  1 file changed, 5 insertions(+), 3 deletions(-)
>>>
>>>  diff --git a/fs/ext4/super.c b/fs/ext4/super.c
>>>  index 43f680c750ae..c4307dc04687 100644
>>>  --- a/fs/ext4/super.c
>>>  +++ b/fs/ext4/super.c
>>>  @@ -1256,9 +1256,11 @@ static void ext4_group_desc_free(struct ext4_sb_info *sbi)
>>>  
>>>  rcu_read_lock();
>>>  group_desc = rcu_dereference(sbi->s_group_desc);
>>>  - for (i = 0; i < sbi->s_gdb_count; i++)
>>>
>> In ext4_group_desc_init(), s_gdb_count is only assigned after kvmalloc_array
>> allocation succeeds. Therefore, when kvmalloc_array fails, the
>> brelse(group_desc[i]) in ext4_group_desc_free() will not actually be
>> executed,
>> and thus this NULL pointer dereference issue will not be triggered.
>
> Thanks for replay, got it, sorry for make noise.
>
> Just then, I find that warning may be trigger:
>
> the kvfree() is called in RCU read critical section, if
> the sbi->s_group_desc pointer comes from vmalloc(),
> the vfree() is called to release it, but the might_sleep()
> is called in the vfree(), this may be trigger warnings in
> rcu_sleep_check() when the enable CONFIG_DEBUG_ATOMIC_SLEEP.

Indeed, vfree triggers the following warning: ```
===========================================================================
EXT4-fs (vdc): unmounting filesystem
c478da00-c52c-4dd4-81c1-d4f93e12ab50. BUG: sleeping function called from
invalid context at mm/vmalloc.c:3441 in_atomic(): 0, irqs_disabled(): 0,
non_block: 0, pid: 457, name: umount preempt_count: 0, expected: 0 RCU
nest depth: 1, expected: 0 CPU: 0 UID: 0 PID: 457 Comm: umount Tainted:
G W 6.19.0-rc4-g4f5e8e6f0123-dirty #10 PREEMPT(none) Tainted: [W]=WARN
Call Trace: <TASK> dump_stack_lvl+0x55/0x70 __might_resched+0x116/0x160
vfree+0x38/0x60 ext4_put_super+0x1ac/0x490
generic_shutdown_super+0x81/0x180 kill_block_super+0x1a/0x40
ext4_kill_sb+0x22/0x40 deactivate_locked_super+0x35/0xb0
cleanup_mnt+0x101/0x170 task_work_run+0x5c/0xa0
exit_to_user_mode_loop+0xe2/0x460 do_syscall_64+0x1de/0x1f0
entry_SYSCALL_64_after_hwframe+0x76/0x7e
===========================================================================
``` And ext4_mb_init_backend, ext4_mb_release, ext4_flex_groups_free
have similar issues.Indeed, vfree triggers the following warning:

===========================================================================
EXT4-fs (vdc): unmounting filesystem c478da00-c52c-4dd4-81c1-d4f93e12ab50.
BUG: sleeping function called from invalid context at mm/vmalloc.c:3441
in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 457, name: umount
preempt_count: 0, expected: 0
RCU nest depth: 1, expected: 0
CPU: 0 UID: 0 PID: 457 Comm: umount Tainted: G W
               6.19.0-rc4-g4f5e8e6f0123-dirty #10 PREEMPT(none)
Tainted: [W]=WARN
Call Trace:
 <TASK>
 dump_stack_lvl+0x55/0x70
 __might_resched+0x116/0x160
 vfree+0x38/0x60
 ext4_put_super+0x1ac/0x490
 generic_shutdown_super+0x81/0x180
 kill_block_super+0x1a/0x40
 ext4_kill_sb+0x22/0x40
 deactivate_locked_super+0x35/0xb0
 cleanup_mnt+0x101/0x170
 task_work_run+0x5c/0xa0
 exit_to_user_mode_loop+0xe2/0x460
 do_syscall_64+0x1de/0x1f0
 entry_SYSCALL_64_after_hwframe+0x76/0x7e
===========================================================================

And ext4_mb_init_backend, ext4_mb_release, ext4_flex_groups_free have
similar issues.

> May be use rcu_access_pointer() to access sbi->s_group_desc
> is enough.
>
Yes, these are all initialization or teardown paths and cannot run
concurrently with
online resize, so using rcu_access_pointer() seems sufficient.

Also, should we add might_sleep() to kvfree() to prevent similar issues?


Cheers,
Baokun


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

* Re: [PATCH] ext4: Fix possible NULL pointer dereference in ext4_group_desc_free()
  2026-03-17  6:32     ` Baokun Li
@ 2026-03-17 13:23       ` Zqiang
  0 siblings, 0 replies; 5+ messages in thread
From: Zqiang @ 2026-03-17 13:23 UTC (permalink / raw)
  To: Baokun Li; +Cc: linux-ext4, linux-kernel, tytso, adilger.kernel, libaokun

> 
> On 3/17/26 7:33 AM, Zqiang wrote:
> 
> > 
> > > 
> > > On 3/16/26 4:20 PM, Zqiang wrote:
> > > 
> >  This can happen if the kvmalloc_objs() fails and sbi->s_group_desc pointer
> >  is NULL in the ext4_group_desc_init(), and then the ext4_group_desc_free()
> >  is called, leading to a NULL group_desc pointer dereference.
> > 
> >  This commit therefore adds a NULL check for sbi->s_group_desc before
> >  accessing its internal members.
> > 
> >  Signed-off-by: Zqiang <qiang.zhang@linux.dev>
> >  ---
> >  fs/ext4/super.c | 8 +++++---
> >  1 file changed, 5 insertions(+), 3 deletions(-)
> > 
> >  diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> >  index 43f680c750ae..c4307dc04687 100644
> >  --- a/fs/ext4/super.c
> >  +++ b/fs/ext4/super.c
> >  @@ -1256,9 +1256,11 @@ static void ext4_group_desc_free(struct ext4_sb_info *sbi)
> >  
> >  rcu_read_lock();
> >  group_desc = rcu_dereference(sbi->s_group_desc);
> >  - for (i = 0; i < sbi->s_gdb_count; i++)
> > 
> > > 
> > > In ext4_group_desc_init(), s_gdb_count is only assigned after kvmalloc_array
> > >  allocation succeeds. Therefore, when kvmalloc_array fails, the
> > >  brelse(group_desc[i]) in ext4_group_desc_free() will not actually be
> > >  executed,
> > >  and thus this NULL pointer dereference issue will not be triggered.
> > > 
> >  Thanks for replay, got it, sorry for make noise.
> > 
> >  Just then, I find that warning may be trigger:
> > 
> >  the kvfree() is called in RCU read critical section, if
> >  the sbi->s_group_desc pointer comes from vmalloc(),
> >  the vfree() is called to release it, but the might_sleep()
> >  is called in the vfree(), this may be trigger warnings in
> >  rcu_sleep_check() when the enable CONFIG_DEBUG_ATOMIC_SLEEP.
> > 
> Indeed, vfree triggers the following warning: ```
> ===========================================================================
> EXT4-fs (vdc): unmounting filesystem
> c478da00-c52c-4dd4-81c1-d4f93e12ab50. BUG: sleeping function called from
> invalid context at mm/vmalloc.c:3441 in_atomic(): 0, irqs_disabled(): 0,
> non_block: 0, pid: 457, name: umount preempt_count: 0, expected: 0 RCU
> nest depth: 1, expected: 0 CPU: 0 UID: 0 PID: 457 Comm: umount Tainted:
> G W 6.19.0-rc4-g4f5e8e6f0123-dirty #10 PREEMPT(none) Tainted: [W]=WARN
> Call Trace: <TASK> dump_stack_lvl+0x55/0x70 __might_resched+0x116/0x160
> vfree+0x38/0x60 ext4_put_super+0x1ac/0x490
> generic_shutdown_super+0x81/0x180 kill_block_super+0x1a/0x40
> ext4_kill_sb+0x22/0x40 deactivate_locked_super+0x35/0xb0
> cleanup_mnt+0x101/0x170 task_work_run+0x5c/0xa0
> exit_to_user_mode_loop+0xe2/0x460 do_syscall_64+0x1de/0x1f0
> entry_SYSCALL_64_after_hwframe+0x76/0x7e


This can also actually happen, depending on your kernel configuration:
 CONFIG_PREEMPT_NONE=y 
 CONFIG_PROVE_RCU=y
 CONFIG_DEBUG_ATOMIC_SLEEP=y
 CONFIG_PREEMPT_RCU=n
 CONFIG_PREEMPT_COUNT=y
 CONFIG_DEBUG_PREEMPT=y


./include/linux/rcupdate.h:409 Illegal context switch in RCU read-side critical section!

other info that might help us debug this:

rcu_scheduler_active = 2, debug_locks = 1
2 locks held by umount/555:
 #0: ffff88800da680e8 (&type->s_umount_key#29){++++}-{4:4}, at: deactivate_super+0x76/0xa0
 #1: ffffffff86a0e580 (rcu_read_lock){....}-{1:3}, at: ext4_group_desc_free+0x27/0x270

Call Trace:
 <TASK>
 dump_stack_lvl+0xbb/0xd0
 dump_stack+0x14/0x20
 lockdep_rcu_suspicious+0x15a/0x1b0
 __might_resched+0x375/0x4d0
 ? put_object.part.0+0x2c/0x50
 __might_sleep+0x108/0x160
 vfree+0x58/0x910
 ? ext4_group_desc_free+0x27/0x270
 kvfree+0x23/0x40
 ext4_group_desc_free+0x111/0x270
 ext4_put_super+0x3c8/0xd40
 generic_shutdown_super+0x14c/0x4a0
 ? __pfx_shrinker_free+0x10/0x10
 kill_block_super+0x40/0x90
 ext4_kill_sb+0x6d/0xb0
 deactivate_locked_super+0xb4/0x180
 deactivate_super+0x7e/0xa0
 cleanup_mnt+0x296/0x3e0
 __cleanup_mnt+0x16/0x20
 task_work_run+0x157/0x250
 ? __pfx_task_work_run+0x10/0x10
 ? exit_to_user_mode_loop+0x6a/0x550
 exit_to_user_mode_loop+0x102/0x550
 do_syscall_64+0x44a/0x500
 entry_SYSCALL_64_after_hwframe+0x77/0x7f



> ===========================================================================
> ``` And ext4_mb_init_backend, ext4_mb_release, ext4_flex_groups_free
> have similar issues.Indeed, vfree triggers the following warning:
> 
> ===========================================================================
> EXT4-fs (vdc): unmounting filesystem c478da00-c52c-4dd4-81c1-d4f93e12ab50.
> BUG: sleeping function called from invalid context at mm/vmalloc.c:3441
> in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 457, name: umount
> preempt_count: 0, expected: 0
> RCU nest depth: 1, expected: 0
> CPU: 0 UID: 0 PID: 457 Comm: umount Tainted: G W
>                6.19.0-rc4-g4f5e8e6f0123-dirty #10 PREEMPT(none)
> Tainted: [W]=WARN
> Call Trace:
>  <TASK>
>  dump_stack_lvl+0x55/0x70
>  __might_resched+0x116/0x160
>  vfree+0x38/0x60
>  ext4_put_super+0x1ac/0x490
>  generic_shutdown_super+0x81/0x180
>  kill_block_super+0x1a/0x40
>  ext4_kill_sb+0x22/0x40
>  deactivate_locked_super+0x35/0xb0
>  cleanup_mnt+0x101/0x170
>  task_work_run+0x5c/0xa0
>  exit_to_user_mode_loop+0xe2/0x460
>  do_syscall_64+0x1de/0x1f0
>  entry_SYSCALL_64_after_hwframe+0x76/0x7e
> ===========================================================================
> 
> And ext4_mb_init_backend, ext4_mb_release, ext4_flex_groups_free have
> similar issues.
> 
> > 
> > May be use rcu_access_pointer() to access sbi->s_group_desc
> >  is enough.
> > 
> Yes, these are all initialization or teardown paths and cannot run
> concurrently with
> online resize, so using rcu_access_pointer() seems sufficient.

Will make a patch and CC you :)

> 
> Also, should we add might_sleep() to kvfree() to prevent similar issues?

I think it makes sense.

Thanks
Zqiang

> 
> Cheers,
> Baokun
>

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

end of thread, other threads:[~2026-03-17 13:23 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-16  8:20 [PATCH] ext4: Fix possible NULL pointer dereference in ext4_group_desc_free() Zqiang
2026-03-16 15:49 ` Baokun Li
2026-03-16 23:33   ` Zqiang
2026-03-17  6:32     ` Baokun Li
2026-03-17 13:23       ` Zqiang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox