* [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
* 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
* [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 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).