stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] udf: Fix NULL ptr deref when converting from inline format
       [not found] <20220118095449.2937-1-jack@suse.cz>
@ 2022-01-18  9:57 ` Jan Kara
  2022-01-20  9:05   ` Christoph Hellwig
  2022-01-18  9:57 ` [PATCH 2/2] udf: Restore i_lenAlloc when inode expansion fails Jan Kara
  1 sibling, 1 reply; 5+ messages in thread
From: Jan Kara @ 2022-01-18  9:57 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: butt3rflyh4ck, Jan Kara, stable

udf_expand_file_adinicb() calls directly ->writepage to write data
expanded into a page. This however misses to setup inode for writeback
properly and so we can crash on inode->i_wb dereference when submitting
page for IO like:

  BUG: kernel NULL pointer dereference, address: 0000000000000158
  #PF: supervisor read access in kernel mode
...
  <TASK>
  __folio_start_writeback+0x2ac/0x350
  __block_write_full_page+0x37d/0x490
  udf_expand_file_adinicb+0x255/0x400 [udf]
  udf_file_write_iter+0xbe/0x1b0 [udf]
  new_sync_write+0x125/0x1c0
  vfs_write+0x28e/0x400

Fix the problem by marking the page dirty and going through the standard
writeback path to write the page. Strictly speaking we would not even
have to write the page but we want to catch e.g. ENOSPC errors early.

Reported-by: butt3rflyh4ck <butterflyhuangxx@gmail.com>
CC: stable@vger.kernel.org
Fixes: 52ebea749aae ("writeback: make backing_dev_info host cgroup-specific bdi_writebacks")
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/udf/inode.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 1d6b7a50736b..d6aa506b6b58 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -258,10 +258,6 @@ int udf_expand_file_adinicb(struct inode *inode)
 	char *kaddr;
 	struct udf_inode_info *iinfo = UDF_I(inode);
 	int err;
-	struct writeback_control udf_wbc = {
-		.sync_mode = WB_SYNC_NONE,
-		.nr_to_write = 1,
-	};
 
 	WARN_ON_ONCE(!inode_is_locked(inode));
 	if (!iinfo->i_lenAlloc) {
@@ -305,8 +301,10 @@ int udf_expand_file_adinicb(struct inode *inode)
 		iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
 	/* from now on we have normal address_space methods */
 	inode->i_data.a_ops = &udf_aops;
+	set_page_dirty(page);
+	unlock_page(page);
 	up_write(&iinfo->i_data_sem);
-	err = inode->i_data.a_ops->writepage(page, &udf_wbc);
+	err = filemap_fdatawrite(inode->i_mapping);
 	if (err) {
 		/* Restore everything back so that we don't lose data... */
 		lock_page(page);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] udf: Restore i_lenAlloc when inode expansion fails
       [not found] <20220118095449.2937-1-jack@suse.cz>
  2022-01-18  9:57 ` [PATCH 1/2] udf: Fix NULL ptr deref when converting from inline format Jan Kara
@ 2022-01-18  9:57 ` Jan Kara
  2022-01-20  9:06   ` Christoph Hellwig
  1 sibling, 1 reply; 5+ messages in thread
From: Jan Kara @ 2022-01-18  9:57 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: butt3rflyh4ck, Jan Kara, stable

When we fail to expand inode from inline format to a normal format, we
restore inode to contain the original inline formatting but we forgot to
set i_lenAlloc back. The mismatch between i_lenAlloc and i_size was then
causing further problems such as warnings and lost data down the line.

Reported-by: butt3rflyh4ck <butterflyhuangxx@gmail.com>
CC: stable@vger.kernel.org
Fixes: 7e49b6f2480c ("udf: Convert UDF to new truncate calling sequence")
Signed-off-by: Jan Kara <jack@suse.cz>
---
 fs/udf/inode.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index d6aa506b6b58..ea8f6cd01f50 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -315,6 +315,7 @@ int udf_expand_file_adinicb(struct inode *inode)
 		unlock_page(page);
 		iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
 		inode->i_data.a_ops = &udf_adinicb_aops;
+		iinfo->i_lenAlloc = inode->i_size;
 		up_write(&iinfo->i_data_sem);
 	}
 	put_page(page);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] udf: Fix NULL ptr deref when converting from inline format
  2022-01-18  9:57 ` [PATCH 1/2] udf: Fix NULL ptr deref when converting from inline format Jan Kara
@ 2022-01-20  9:05   ` Christoph Hellwig
  0 siblings, 0 replies; 5+ messages in thread
From: Christoph Hellwig @ 2022-01-20  9:05 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel, butt3rflyh4ck, stable

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] udf: Restore i_lenAlloc when inode expansion fails
  2022-01-18  9:57 ` [PATCH 2/2] udf: Restore i_lenAlloc when inode expansion fails Jan Kara
@ 2022-01-20  9:06   ` Christoph Hellwig
  2022-01-20 11:19     ` Jan Kara
  0 siblings, 1 reply; 5+ messages in thread
From: Christoph Hellwig @ 2022-01-20  9:06 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel, butt3rflyh4ck, stable

On Tue, Jan 18, 2022 at 10:57:48AM +0100, Jan Kara wrote:
> When we fail to expand inode from inline format to a normal format, we
> restore inode to contain the original inline formatting but we forgot to
> set i_lenAlloc back. The mismatch between i_lenAlloc and i_size was then
> causing further problems such as warnings and lost data down the line.

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

Btw, how did the reported even hit that failure in a way where the
file system continues working?  If we fail to write back data we'd
probably better stop modifying anything and bail out..

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 2/2] udf: Restore i_lenAlloc when inode expansion fails
  2022-01-20  9:06   ` Christoph Hellwig
@ 2022-01-20 11:19     ` Jan Kara
  0 siblings, 0 replies; 5+ messages in thread
From: Jan Kara @ 2022-01-20 11:19 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Jan Kara, linux-fsdevel, butt3rflyh4ck, stable

On Thu 20-01-22 01:06:03, Christoph Hellwig wrote:
> On Tue, Jan 18, 2022 at 10:57:48AM +0100, Jan Kara wrote:
> > When we fail to expand inode from inline format to a normal format, we
> > restore inode to contain the original inline formatting but we forgot to
> > set i_lenAlloc back. The mismatch between i_lenAlloc and i_size was then
> > causing further problems such as warnings and lost data down the line.
> 
> Looks good,
> 
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> 
> Btw, how did the reported even hit that failure in a way where the
> file system continues working?  If we fail to write back data we'd
> probably better stop modifying anything and bail out..

We can fail the expansion from inline to out-of-line format e.g. when the
filesystem is full (ENOSPC). So we have to handle that case gracefully and
the filesystem should be fully operational after this.

Thanks for review!


								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-01-20 11:19 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20220118095449.2937-1-jack@suse.cz>
2022-01-18  9:57 ` [PATCH 1/2] udf: Fix NULL ptr deref when converting from inline format Jan Kara
2022-01-20  9:05   ` Christoph Hellwig
2022-01-18  9:57 ` [PATCH 2/2] udf: Restore i_lenAlloc when inode expansion fails Jan Kara
2022-01-20  9:06   ` Christoph Hellwig
2022-01-20 11:19     ` Jan Kara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).