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: <20230827164944.52560-1-n.zhandarovich@fintech.ru>
Date:   Sun, 27 Aug 2023 09:49:44 -0700
From:   Nikita Zhandarovich <n.zhandarovich@...tech.ru>
To:     Konstantin Komarov <almaz.alexandrovich@...agon-software.com>
CC:     Nikita Zhandarovich <n.zhandarovich@...tech.ru>,
        <ntfs3@...ts.linux.dev>, <linux-kernel@...r.kernel.org>,
        <syzbot+9d014e6e0df70d97c103@...kaller.appspotmail.com>
Subject: [PATCH] fs: ntfs3: fix possible NULL-ptr-deref in ni_readpage_cmpr()

Syzkaller identified a possible issue with calling unlock_page() for
pages that have not been correctly allocated by
find_or_create_page(), leading to possible NULL pointer dereferences
among other issues.

Specifically, in case of an error with aforementioned
find_or_create_page() function due to memory issues,
ni_readpage_cmpr() attempts to erroneously unlock and release all
elements of 'pages'.

This patch ensures that we only deal with the pages successfully
allocated with calls to find_or_create_page().

Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation")
Reported-by: syzbot+9d014e6e0df70d97c103@...kaller.appspotmail.com
Signed-off-by: Nikita Zhandarovich <n.zhandarovich@...tech.ru>
---
 fs/ntfs3/frecord.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
index 16bd9faa2d28..9789b2ac7e2d 100644
--- a/fs/ntfs3/frecord.c
+++ b/fs/ntfs3/frecord.c
@@ -2095,7 +2095,7 @@ int ni_readpage_cmpr(struct ntfs_inode *ni, struct page *page)
 	struct page **pages = NULL; /* Array of at most 16 pages. stack? */
 	u8 frame_bits;
 	CLST frame;
-	u32 i, idx, frame_size, pages_per_frame;
+	u32 i, idx, frame_size, pages_per_frame, pages_created = 0;
 	gfp_t gfp_mask;
 	struct page *pg;
 
@@ -2138,6 +2138,7 @@ int ni_readpage_cmpr(struct ntfs_inode *ni, struct page *page)
 			goto out1;
 		}
 		pages[i] = pg;
+		pages_created++;
 	}
 
 	err = ni_read_frame(ni, frame_vbo, pages, pages_per_frame);
@@ -2146,7 +2147,7 @@ int ni_readpage_cmpr(struct ntfs_inode *ni, struct page *page)
 	if (err)
 		SetPageError(page);
 
-	for (i = 0; i < pages_per_frame; i++) {
+	for (i = 0; i < pages_created; i++) {
 		pg = pages[i];
 		if (i == idx)
 			continue;
-- 
2.25.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ