fs/jffs2/summary.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
When the first write after mounting does not fit into the remaining
space of the nextblock, jffs2_do_reserve_space() closes the block via
the summary path and calls jffs2_sum_write_sumnode() to write out the
collected summary information. However, if no node has been written
into the nextblock since it was selected during mount, the summary
collection is legitimately empty and jffs2_sum_write_sumnode() hits
BUG() on the empty-collection check.
This is reachable with a crafted filesystem image: the only partially
dirty eraseblock picked as nextblock at scan time has too little free
space (e.g. 140 bytes) for the first reservation including the summary
frame, so the block gets closed before anything was written into it:
jffs2: warning: (4872) jffs2_sum_write_sumnode: Empty summary info!!!
kernel BUG at fs/jffs2/summary.c:868!
Call Trace:
jffs2_sum_write_sumnode
jffs2_do_reserve_space
jffs2_reserve_space
jffs2_symlink+0x172
vfs_symlink
filename_symlinkat
__x64_sys_symlink
An empty collection is a valid state: there is nothing to summarize for
a block that the kernel has not written to in this cycle. Instead of
BUG(), disable summary collection for this block and return. The caller
then falls back to the existing non-summary restart path
(JFFS2_SUMMARY_NOSUM_SIZE) and either uses the remaining space without
summary reservation or closes the block.
Reported-by: syzbot+0727f46a0571de01bf93@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=0727f46a0571de01bf93
Link: https://lore.kernel.org/linux-mtd/20261015145341.34322-1-me@eltavine.com/
Suggested-by: eltavine <me@eltavine.com>
Signed-off-by: Shuai Liu <847807867@qq.com>
---
fs/jffs2/summary.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index 4521a7723f30..1e4a19df4c49 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -864,8 +864,17 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
goto out;
if (!c->summary->sum_num || !c->summary->sum_list_head) {
- JFFS2_WARNING("Empty summary info!!!\n");
- BUG();
+ /* Nothing was written into this block since it became the
+ * nextblock, e.g. when the first write after mounting does
+ * not fit into the remaining space of the block. There is no
+ * summary information to write out, disable summary
+ * collection for this block and let the caller fall back to
+ * the non-summary path.
+ */
+ dbg_summary("empty summary info for jeb at 0x%08x\n",
+ jeb->offset);
+ jffs2_sum_disable_collecting(c->summary);
+ goto out;
}
datasize = c->summary->sum_size + sizeof(struct jffs2_sum_marker);
--
2.43.0
© 2016 - 2026 Red Hat, Inc.