Re: [BUG] general protection fault in jffs2_xattr_delete_inode

Zhan Xusheng <[email protected]>
Newsgroups org.infradead.lists.linux-mtd,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On Thu, 20 Aug 2026 03:28:04 +0900, Jaeyoung Chung wrote:
> We have not analyzed the root cause, so we do not have a proposed fix
> to offer.

f->inocache is never initialised, and jffs2_new_inode() has two error paths
that evict the inode before it gets assigned.

Your log says it outright.  RSI is the ic argument:

  RSI: 6464646464646464
  RBX: 646464646464648c
  1f: 48 8d 5e 28   lea 0x28(%rsi),%rbx

0x64 is 'd', and th_churn() does memset(p + 1, 'a' + (idx & 7), 3998) with
idx 3.  So ic is not a stale pointer to anything, it is the pathname bytes
that thread left lying in the page the inode was later carved from.  With
CONFIG_JFFS2_FS_XATTR the 0x28 is pino_nlink, so the faulting access is the
ic->pino_nlink of xattr.c:602.

Nothing initialises that field.  jffs2_inode_cachep has a constructor, and
jffs2_i_init_once() only does mutex_init(), target = NULL and
inode_init_once().  jffs2_alloc_inode() allocates with plain GFP_KERNEL, so
no zeroing.  jffs2_init_inode_info() sets seven fields and inocache is not
among them.  inocache also sits before vfs_inode in the struct, so
inode_init_always() does not reach it.

On this path f->inocache is assigned only by jffs2_do_new_inode(),
write.c:35.  Both of these return before that, and both then do
make_bad_inode() and iput():

  fs.c:459  jffs2_init_acl_pre() fails
  fs.c:466  jffs2_do_new_inode() fails in jffs2_alloc_inode_cache(),
            write.c:28

Either is an allocation failure, so fail-nth reaches both.  The inode is
unhashed, so inode_generic_drop() makes iput() evict it, which is the
evict() -> jffs2_do_clear_inode() -> jffs2_xattr_delete_inode() in your
trace.  The mdelay() before new_inode() gives the churn threads a window to
leave their bytes where the inode is then carved from.

mtd/next has the same jffs2_init_inode_info(), so:

--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -55,6 +55,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
 	f->metadata = NULL;
 	f->dents = NULL;
 	f->target = NULL;
+	f->inocache = NULL;
 	f->flags = 0;
 	f->usercompr = 0;
 }

Both callers assign inocache immediately afterwards, jffs2_do_read_inode()
at readinode.c:1335 as its first act and jffs2_do_new_inode() at write.c:35,
and jffs2_xattr_delete_inode() returns early on a NULL ic, so the read path
is unaffected.

I have not run your reproducer, so please confirm it on your setup before
this goes out as a patch.

Thanks,
Zhan Xusheng

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.