lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20251118001833.423470-2-eraykrdg1@gmail.com>
Date: Tue, 18 Nov 2025 03:18:34 +0300
From: Ahmet Eray Karadag <eraykrdg1@...il.com>
To: mark@...heh.com,
	jlbec@...lplan.org,
	joseph.qi@...ux.alibaba.com
Cc: ocfs2-devel@...ts.linux.dev,
	linux-kernel@...r.kernel.org,
	david.hunter.linux@...il.com,
	skhan@...uxfoundation.org,
	Ahmet Eray Karadag <eraykrdg1@...il.com>,
	syzbot+b93b65ee321c97861072@...kaller.appspotmail.com,
	Heming Zhao <heming.zhao@...e.com>,
	Albin Babu Varghese <albinbabuvarghese20@...il.com>
Subject: [PATCH] ocfs2: Mark inode bad upon validation failure during read

A VFS cache inconsistency, potentially triggered by sequences like
buffered writes followed by open(O_DIRECT), can result in an invalid
on-disk inode block (e.g., bad signature). OCFS2 detects this corruption
when reading the inode block via ocfs2_validate_inode_block(), logs
"Invalid dinode", and often switches the filesystem to read-only mode.

The VFS open(O_DIRECT) operation appears to incorrectly clear the inode's
I_DIRTY flag without ensuring the dirty metadata (reflecting the earlier
buffered write, e.g., an updated i_size) is flushed to disk. This leaves
the in-memory VFS inode object "in limbo" with an updated size (e.g., 38639
from the write) but marked clean, while its on-disk counterpart remains
stale (e.g., size 0) or invalid.

Currently, the function reading the inode block (ocfs2_read_inode_block_full())
fails to call make_bad_inode() upon detecting the validation error.
Because the in-memory inode is not marked bad, subsequent operations
(like ftruncate) proceed erroneously. They eventually reach code
(e.g., ocfs2_truncate_file()) that compares the inconsistent
in-memory size (38639) against the invalid/stale on-disk size (0), leading
to kernel crashes via BUG_ON.

Fix this by calling make_bad_inode(inode) within the error handling path of
ocfs2_read_inode_block_full() immediately after a block read or validation
error occurs. This ensures VFS is properly notified about the
corrupt inode at the point of detection. Marking the inode bad  allows VFS
to correctly fail subsequent operations targeting this inode early,
preventing kernel panics caused by operating on known inconsistent inode states.

Reported-by: syzbot+b93b65ee321c97861072@...kaller.appspotmail.com
Link: https://syzkaller.appspot.com/bug?extid=b93b65ee321c97861072
Reviewed-by: Heming Zhao <heming.zhao@...e.com>
Co-developed-by: Albin Babu Varghese <albinbabuvarghese20@...il.com>
Signed-off-by: Albin Babu Varghese <albinbabuvarghese20@...il.com>
Signed-off-by: Ahmet Eray Karadag <eraykrdg1@...il.com>
Previous-link: https://lore.kernel.org/all/20251029225748.11361-2-eraykrdg1@gmail.com/T/
---
 fs/ocfs2/inode.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index fcc89856ab95..415ad29ec758 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -1690,6 +1690,8 @@ int ocfs2_read_inode_block_full(struct inode *inode, struct buffer_head **bh,
 	rc = ocfs2_read_blocks(INODE_CACHE(inode), OCFS2_I(inode)->ip_blkno,
 			       1, &tmp, flags, ocfs2_validate_inode_block);
 
+	if (rc < 0)
+		make_bad_inode(inode);
 	/* If ocfs2_read_blocks() got us a new bh, pass it up. */
 	if (!rc && !*bh)
 		*bh = tmp;
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ