Re: [BUG] ext4: NULL/invalid pointer dereference in ext4_writepages() during generic/039

Ojaswin Mujoo <[email protected]> Tue, 4 Aug 2026 01:18:49 +0530
Newsgroups org.kernel.vger.linux-ext4,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On Mon, Aug 03, 2026 at 12:22:35PM +0530, Ojaswin Mujoo wrote:
> On Mon, Aug 03, 2026 at 10:17:35AM +0530, Venkat Rao Bagalkote wrote:
> > Hi,
> > 
> > I am  seeing a reproducible kernel crash while running xfstests generic/039
> > on powerpc.
> > 
> > The crash happens during ext4 journal recovery while mounting the
> > filesystem. The fault occurs inside ext4_writepages() and appears to
> > dereference a userspace-looking address.
> > 
> > Test environment
> > ----------------
> > Kernel:
> >   7.2.0-rc5-next-20260731
> > 
> > Architecture:
> >   powerpc64le
> > 
> > Platform:
> >   IBM Power9 (pSeries)
> > 
> > Machine:
> >   IBM,8375-42A
> >   FW950.80 (VL950_131)
> > 
> > Config highlights:
> >   PAGE_SIZE=64K
> >   MMU=Hash
> >   PREEMPTLAZY=y
> > 
> > Workload
> > --------
> > xfstests generic/039
> > 
> > Log excerpt:
> >   run fstests generic/039 at 2026-08-03 00:22:44
> > 
> > Crash
> > -----
> > [  615.063689] Kernel attempted to read user page (fe73f0000) - exploit
> > attempt? (uid: 0)
> > [  615.063714] BUG: Unable to handle kernel data access on read at
> > 0xfe73f0000
> > [  615.063723] Faulting instruction address: 0xc008000015b0ed24
> > [  615.063731] Oops: Kernel access of bad area, sig: 11 [#1]
> > 
> > The faulting instruction is:
> > 
> >   ext4_writepages+0x12c/0x3a0
> > 
> > Relevant call trace:
> > 
> >   ext4_writepages
> >   do_writepages
> >   __writeback_single_inode
> >   writeback_single_inode
> >   write_inode_now
> >   iput_final
> >   ext4_fc_replay
> >   do_one_pass
> >   jbd2_journal_recover
> >   jbd2_journal_load
> >   ext4_load_journal
> >   ext4_load_and_init_journal
> >   __ext4_fill_super
> >   ext4_fill_super
> >   get_tree_bdev_flags
> >   ext4_get_tree
> >   vfs_get_tree
> >   vfs_cmd_create
> >   __do_sys_fsconfig
> > 
> > Full trace:
> > 
> > [  615.064100] NIP [c008000015b0ed24] ext4_writepages+0x12c/0x3a0 [ext4]
> > [  615.064360] Call Trace:
> > [  615.064383] do_writepages+0x190/0x330
> > [  615.064395] __writeback_single_inode+0x9c/0x9e0
> > [  615.064411] writeback_single_inode+0x18c/0x2b0
> > [  615.064425] write_inode_now+0xc0/0x100
> > [  615.064439] iput_final+0x10c/0x300
> > [  615.064451] ext4_fc_replay+0x374/0xdd0 [ext4]
> > [  615.064583] do_one_pass+0x9bc/0x1370 [jbd2]
> > [  615.064627] jbd2_journal_recover[0x358/0x400 [jbd2]
> > [  [jbd2615.064670] jbd2_journal_load/0x110 [jbd2]
> > [  615.064712] ext4_load_journal+0x2a0/0xb00 [ext4]
> > [  615.064844] ext4_load_and_init_journal+0x6c/0x660 [ext4]
> > [  615.064976] __ext4_fill_super+0x20b0/0x23a0 [ext4]
> > 
> > Registers:
> > 
> >   DAR:   0x0000000fe73f0000
> >   DSISR: 0x40000000
> > 
> > The address being dereferenced (0xfe73f0000) looks like a userspace
> > address and triggers:
> > 
> >   "Kernel attempted to read user page - exploit attempt?"
> > 
> > 
> > Filesystem messages immediately prior to the crash:
> > 
> > [  614.718310] EXT4-fs (loop0): mounted filesystem
> > ee09878a-da42-4d97-81ed-1b9616af2fb4 r/w with ordered data mode. Quota mode:
> > journalled.
> > [  614.984409] EXT4-fs (dm-0): mounted filesystem
> > b60397dc-c40f-4c75-bba9-bfc21f3a905a r/w with ordered data mode. Quota mode:
> > journalled.
> > [  615.029979] EXT4-fs (dm-0): unmounting filesystem
> > b60397dc-c40f-4c75-bba9-bfc21f3a905a.
> > 
> > 
> > Meanwhile, I will attempt bisection.
> > 
> > If you happen to fix this issue, please add below tag.
> > 
> > Reported-by: Venkat Rao Bagalkote <[email protected]>
> > 
> 
> Hey thanks for reporting this Venkat, I'll try to replicate this at my
> end.
> 
> In the meantime, can you please share the complete Oops message and also
> your local.config. 
> 
> Thanks,
> ojaswin

(+cc Jan, Christian)

Okay so I'm able to replicate this in an x86 machine as well with 4kb
block size. The issue is replicable in vfs/vfs.all and is occurring
after Jan's change to nojournal mode writeout [1], with fast_commit.

The issue is as follows:

  __ext4_fill_super
    ext4_load_and_init_journal
      ...
      jbd2_journal_recover
        do_one_pass
          fc_do_one_pass
            ...
            ext4_fc_replay_unlink
              __ext4_unlink
                __ext4_mark_iloc_dirty
                  if (sbi->s_journal == NULL)  // s_journal is not set yet
                    set_inode_metadata_writeback(inode); // sets I_METADATA_WRITEBACK
              iput(inode)
                iput_final(inode)
                  ...
                  writeback_single_inode
                    __writeback_single_inode  // since I_METADATA_WRITEBACK is set
                      ...
                      ext4_writepages
                        ext4_writepages_down_read
                          percpu_down_read(sbi->s_writepages_rwsem)
                             <--- OOPS because this is initialized
                                  later in ext4_percpu_param_init()

A simple fix seems to be to move ext4_percpu_param_init() call before
ext4_load_journal() so that we can safely call ext4_writepages(). The
below diff seems to be fixing the issue for me, does this look okay to
you Jan?

Also, venkat can you please help test this in your system:

diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 2877a6cf6d09..6e05f191542c 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -5511,6 +5511,10 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
                        goto failed_mount3a;
        }

+       err = ext4_percpu_param_init(sbi);
+       if (err)
+               goto failed_mount3a;
+
        err = -EINVAL;
        /*
         * The first inode we look at is the journal inode.  Don't try
@@ -5659,10 +5663,6 @@ static int __ext4_fill_super(struct fs_context *fc, struct super_block *sb)
                        clear_opt2(sb, MB_OPTIMIZE_SCAN);
        }

-       err = ext4_percpu_param_init(sbi);
-       if (err)
-               goto failed_mount5;
-
        err = ext4_mb_init(sb);
        if (err) {
                ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)",
@@ -5764,7 +5764,6 @@ failed_mount8: __maybe_unused
        ext4_mb_release(sb);
        ext4_flex_groups_free(sbi);
 failed_mount5:
-       ext4_percpu_param_destroy(sbi);
        ext4_ext_release(sb);
        ext4_release_system_zone(sb);
 failed_mount4a:
@@ -5785,6 +5784,7 @@ failed_mount8: __maybe_unused
                ext4_journal_destroy(sbi, sbi->s_journal);
        }
 failed_mount3a:
+       ext4_percpu_param_destroy(sbi);
        ext4_es_unregister_shrinker(sbi);
 failed_mount3:
        /* flush s_sb_upd_work before sbi destroy */

[1] https://lore.kernel.org/linux-ext4/[email protected]/
> > 
> > 
> > Thanks,
> > Venkat.
> >