From: Greg Kroah-Hartman Date: Tue, 16 Jul 2024 13:30:07 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v4.19.318~26 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=37406c6da12ede5fe78f1689de2e7733e28d4648;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: nilfs2-fix-kernel-bug-on-rename-operation-of-broken-directory.patch --- diff --git a/queue-5.10/nilfs2-fix-kernel-bug-on-rename-operation-of-broken-directory.patch b/queue-5.10/nilfs2-fix-kernel-bug-on-rename-operation-of-broken-directory.patch new file mode 100644 index 00000000000..ed46a3e48d8 --- /dev/null +++ b/queue-5.10/nilfs2-fix-kernel-bug-on-rename-operation-of-broken-directory.patch @@ -0,0 +1,78 @@ +From a9e1ddc09ca55746079cc479aa3eb6411f0d99d4 Mon Sep 17 00:00:00 2001 +From: Ryusuke Konishi +Date: Sat, 29 Jun 2024 01:51:07 +0900 +Subject: nilfs2: fix kernel bug on rename operation of broken directory + +From: Ryusuke Konishi + +commit a9e1ddc09ca55746079cc479aa3eb6411f0d99d4 upstream. + +Syzbot reported that in rename directory operation on broken directory on +nilfs2, __block_write_begin_int() called to prepare block write may fail +BUG_ON check for access exceeding the folio/page size. + +This is because nilfs_dotdot(), which gets parent directory reference +entry ("..") of the directory to be moved or renamed, does not check +consistency enough, and may return location exceeding folio/page size for +broken directories. + +Fix this issue by checking required directory entries ("." and "..") in +the first chunk of the directory in nilfs_dotdot(). + +Link: https://lkml.kernel.org/r/20240628165107.9006-1-konishi.ryusuke@gmail.com +Signed-off-by: Ryusuke Konishi +Reported-by: syzbot+d3abed1ad3d367fa2627@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=d3abed1ad3d367fa2627 +Fixes: 2ba466d74ed7 ("nilfs2: directory entry operations") +Tested-by: Ryusuke Konishi +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + fs/nilfs2/dir.c | 32 ++++++++++++++++++++++++++++++-- + 1 file changed, 30 insertions(+), 2 deletions(-) + +--- a/fs/nilfs2/dir.c ++++ b/fs/nilfs2/dir.c +@@ -396,11 +396,39 @@ found: + + struct nilfs_dir_entry *nilfs_dotdot(struct inode *dir, struct page **p) + { +- struct nilfs_dir_entry *de = nilfs_get_page(dir, 0, p); ++ struct page *page; ++ struct nilfs_dir_entry *de, *next_de; ++ size_t limit; ++ char *msg; + ++ de = nilfs_get_page(dir, 0, &page); + if (IS_ERR(de)) + return NULL; +- return nilfs_next_entry(de); ++ ++ limit = nilfs_last_byte(dir, 0); /* is a multiple of chunk size */ ++ if (unlikely(!limit || le64_to_cpu(de->inode) != dir->i_ino || ++ !nilfs_match(1, ".", de))) { ++ msg = "missing '.'"; ++ goto fail; ++ } ++ ++ next_de = nilfs_next_entry(de); ++ /* ++ * If "next_de" has not reached the end of the chunk, there is ++ * at least one more record. Check whether it matches "..". ++ */ ++ if (unlikely((char *)next_de == (char *)de + nilfs_chunk_size(dir) || ++ !nilfs_match(2, "..", next_de))) { ++ msg = "missing '..'"; ++ goto fail; ++ } ++ *p = page; ++ return next_de; ++ ++fail: ++ nilfs_error(dir->i_sb, "directory #%lu %s", dir->i_ino, msg); ++ nilfs_put_page(page); ++ return NULL; + } + + ino_t nilfs_inode_by_name(struct inode *dir, const struct qstr *qstr) diff --git a/queue-5.10/series b/queue-5.10/series index b46cd742b1d..5cb6b66d58d 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -96,3 +96,4 @@ efi-ia64-move-ia64-only-declarations-to-new-asm-efi.h-header.patch ipv6-annotate-data-races-around-cnf.disable_ipv6.patch ipv6-prevent-null-dereference-in-ip6_output.patch bpf-allow-reads-from-uninit-stack.patch +nilfs2-fix-kernel-bug-on-rename-operation-of-broken-directory.patch