[lvc-project] [PATCH] ocfs2: fix buffer head management in ocfs2_read_blocks()

Dmitry Antipov dmantipov at yandex.ru
Fri May 29 12:41:28 MSK 2026


In 'ocfs2_read_blocks()', caller should't assume that buffer head
returned by 'sb_getblk()' is exclusively owned and so 'put_bh()'
always drops b_count from 1 to 0. If it is not so, buffer head
remains on hold and likely to be returned by the next call to
'sb_getblk()' unchanged - that is, with BH_Uptodate bit set even
if it has failed validation previously, thus allowing to insert
that buffer head into OCFS2 metadata cache and submit it to upper
layers. To avoid such a scenario, BH_Uptodate should be cleared
immediately after 'validate()' callback has detected some data
inconsistency.

Reported-by: syzbot+caacd220635a9cc3bac9 at syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=caacd220635a9cc3bac9
Fixes: cf76c78595ca ("ocfs2: don't put and assigning null to bh allocated outside")
Signed-off-by: Dmitry Antipov <dmantipov at yandex.ru>
---
After introducing the series started with 775c17386a6fd ("ocfs2:
validate dx_root extent list fields during block read"), reproducer
from https://syzkaller.appspot.com/bug?extid=30b53487d00b4f7f0922
has started to trigger KASAN use-after-free again, and this patch
should fix this as well.
---
 fs/ocfs2/buffer_head_io.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c
index 701d27d908d4..6114299b121e 100644
--- a/fs/ocfs2/buffer_head_io.c
+++ b/fs/ocfs2/buffer_head_io.c
@@ -350,8 +350,6 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
 						wait_on_buffer(bh);
 					put_bh(bh);
 					bhs[i] = NULL;
-				} else if (bh && buffer_uptodate(bh)) {
-					clear_buffer_uptodate(bh);
 				}
 				continue;
 			}
@@ -380,8 +378,11 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
 				BUG_ON(buffer_jbd(bh));
 				clear_buffer_needs_validate(bh);
 				status = validate(sb, bh);
-				if (status)
+				if (status) {
+					if (buffer_uptodate(bh))
+						clear_buffer_uptodate(bh);
 					goto read_failure;
+				}
 			}
 		}
 
-- 
2.54.0




More information about the lvc-project mailing list