--- /dev/null
+From 298b1e4182d657c3e388adcc29477904e9600ed5 Mon Sep 17 00:00:00 2001
+From: Chao Yu <chao@kernel.org>
+Date: Wed, 29 May 2024 18:01:03 +0800
+Subject: f2fs: fix to truncate preallocated blocks in f2fs_file_open()
+
+From: Chao Yu <chao@kernel.org>
+
+commit 298b1e4182d657c3e388adcc29477904e9600ed5 upstream.
+
+chenyuwen reports a f2fs bug as below:
+
+Unable to handle kernel NULL pointer dereference at virtual address 0000000000000011
+ fscrypt_set_bio_crypt_ctx+0x78/0x1e8
+ f2fs_grab_read_bio+0x78/0x208
+ f2fs_submit_page_read+0x44/0x154
+ f2fs_get_read_data_page+0x288/0x5f4
+ f2fs_get_lock_data_page+0x60/0x190
+ truncate_partial_data_page+0x108/0x4fc
+ f2fs_do_truncate_blocks+0x344/0x5f0
+ f2fs_truncate_blocks+0x6c/0x134
+ f2fs_truncate+0xd8/0x200
+ f2fs_iget+0x20c/0x5ac
+ do_garbage_collect+0x5d0/0xf6c
+ f2fs_gc+0x22c/0x6a4
+ f2fs_disable_checkpoint+0xc8/0x310
+ f2fs_fill_super+0x14bc/0x1764
+ mount_bdev+0x1b4/0x21c
+ f2fs_mount+0x20/0x30
+ legacy_get_tree+0x50/0xbc
+ vfs_get_tree+0x5c/0x1b0
+ do_new_mount+0x298/0x4cc
+ path_mount+0x33c/0x5fc
+ __arm64_sys_mount+0xcc/0x15c
+ invoke_syscall+0x60/0x150
+ el0_svc_common+0xb8/0xf8
+ do_el0_svc+0x28/0xa0
+ el0_svc+0x24/0x84
+ el0t_64_sync_handler+0x88/0xec
+
+It is because inode.i_crypt_info is not initialized during below path:
+- mount
+ - f2fs_fill_super
+ - f2fs_disable_checkpoint
+ - f2fs_gc
+ - f2fs_iget
+ - f2fs_truncate
+
+So, let's relocate truncation of preallocated blocks to f2fs_file_open(),
+after fscrypt_file_open().
+
+Fixes: d4dd19ec1ea0 ("f2fs: do not expose unwritten blocks to user by DIO")
+Reported-by: chenyuwen <yuwen.chen@xjmz.com>
+Closes: https://lore.kernel.org/linux-kernel/20240517085327.1188515-1-yuwen.chen@xjmz.com
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Shivani Agarwal <shivani.agarwal@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/f2fs.h | 1 +
+ fs/f2fs/file.c | 42 +++++++++++++++++++++++++++++++++++++++++-
+ fs/f2fs/inode.c | 8 --------
+ 3 files changed, 42 insertions(+), 9 deletions(-)
+
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -788,6 +788,7 @@ enum {
+ FI_ALIGNED_WRITE, /* enable aligned write */
+ FI_COW_FILE, /* indicate COW file */
+ FI_ATOMIC_COMMITTED, /* indicate atomic commit completed except disk sync */
++ FI_OPENED_FILE, /* indicate file has been opened */
+ FI_MAX, /* max flag, never be used */
+ };
+
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -538,6 +538,42 @@ static int f2fs_file_mmap(struct file *f
+ return 0;
+ }
+
++static int finish_preallocate_blocks(struct inode *inode)
++{
++ int ret;
++
++ inode_lock(inode);
++ if (is_inode_flag_set(inode, FI_OPENED_FILE)) {
++ inode_unlock(inode);
++ return 0;
++ }
++
++ if (!file_should_truncate(inode)) {
++ set_inode_flag(inode, FI_OPENED_FILE);
++ inode_unlock(inode);
++ return 0;
++ }
++
++ f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
++ filemap_invalidate_lock(inode->i_mapping);
++
++ truncate_setsize(inode, i_size_read(inode));
++ ret = f2fs_truncate(inode);
++
++ filemap_invalidate_unlock(inode->i_mapping);
++ f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
++
++ if (!ret)
++ set_inode_flag(inode, FI_OPENED_FILE);
++
++ inode_unlock(inode);
++ if (ret)
++ return ret;
++
++ file_dont_truncate(inode);
++ return 0;
++}
++
+ static int f2fs_file_open(struct inode *inode, struct file *filp)
+ {
+ int err = fscrypt_file_open(inode, filp);
+@@ -554,7 +590,11 @@ static int f2fs_file_open(struct inode *
+
+ filp->f_mode |= FMODE_NOWAIT;
+
+- return dquot_file_open(inode, filp);
++ err = dquot_file_open(inode, filp);
++ if (err)
++ return err;
++
++ return finish_preallocate_blocks(inode);
+ }
+
+ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
+--- a/fs/f2fs/inode.c
++++ b/fs/f2fs/inode.c
+@@ -549,14 +549,6 @@ make_now:
+ }
+ f2fs_set_inode_flags(inode);
+
+- if (file_should_truncate(inode) &&
+- !is_sbi_flag_set(sbi, SBI_POR_DOING)) {
+- ret = f2fs_truncate(inode);
+- if (ret)
+- goto bad_inode;
+- file_dont_truncate(inode);
+- }
+-
+ unlock_new_inode(inode);
+ trace_f2fs_iget(inode);
+ return inode;
--- /dev/null
+From 9eee5330656bf92f51cb1f09b2dc9f8cf975b3d1 Mon Sep 17 00:00:00 2001
+From: Mostafa Saleh <smostafa@google.com>
+Date: Mon, 24 Jun 2024 20:37:28 +0000
+Subject: PCI/MSI: Fix UAF in msi_capability_init
+
+From: Mostafa Saleh <smostafa@google.com>
+
+commit 9eee5330656bf92f51cb1f09b2dc9f8cf975b3d1 upstream.
+
+KFENCE reports the following UAF:
+
+ BUG: KFENCE: use-after-free read in __pci_enable_msi_range+0x2c0/0x488
+
+ Use-after-free read at 0x0000000024629571 (in kfence-#12):
+ __pci_enable_msi_range+0x2c0/0x488
+ pci_alloc_irq_vectors_affinity+0xec/0x14c
+ pci_alloc_irq_vectors+0x18/0x28
+
+ kfence-#12: 0x0000000008614900-0x00000000e06c228d, size=104, cache=kmalloc-128
+
+ allocated by task 81 on cpu 7 at 10.808142s:
+ __kmem_cache_alloc_node+0x1f0/0x2bc
+ kmalloc_trace+0x44/0x138
+ msi_alloc_desc+0x3c/0x9c
+ msi_domain_insert_msi_desc+0x30/0x78
+ msi_setup_msi_desc+0x13c/0x184
+ __pci_enable_msi_range+0x258/0x488
+ pci_alloc_irq_vectors_affinity+0xec/0x14c
+ pci_alloc_irq_vectors+0x18/0x28
+
+ freed by task 81 on cpu 7 at 10.811436s:
+ msi_domain_free_descs+0xd4/0x10c
+ msi_domain_free_locked.part.0+0xc0/0x1d8
+ msi_domain_alloc_irqs_all_locked+0xb4/0xbc
+ pci_msi_setup_msi_irqs+0x30/0x4c
+ __pci_enable_msi_range+0x2a8/0x488
+ pci_alloc_irq_vectors_affinity+0xec/0x14c
+ pci_alloc_irq_vectors+0x18/0x28
+
+Descriptor allocation done in:
+__pci_enable_msi_range
+ msi_capability_init
+ msi_setup_msi_desc
+ msi_insert_msi_desc
+ msi_domain_insert_msi_desc
+ msi_alloc_desc
+ ...
+
+Freed in case of failure in __msi_domain_alloc_locked()
+__pci_enable_msi_range
+ msi_capability_init
+ pci_msi_setup_msi_irqs
+ msi_domain_alloc_irqs_all_locked
+ msi_domain_alloc_locked
+ __msi_domain_alloc_locked => fails
+ msi_domain_free_locked
+ ...
+
+That failure propagates back to pci_msi_setup_msi_irqs() in
+msi_capability_init() which accesses the descriptor for unmasking in the
+error exit path.
+
+Cure it by copying the descriptor and using the copy for the error exit path
+unmask operation.
+
+[ tglx: Massaged change log ]
+
+Fixes: bf6e054e0e3f ("genirq/msi: Provide msi_device_populate/destroy_sysfs()")
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Mostafa Saleh <smostafa@google.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Bjorn Heelgas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20240624203729.1094506-1-smostafa@google.com
+Signed-off-by: Hugo SIMELIERE <hsimeliere.opensource@witekio.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/msi/msi.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/msi/msi.c
++++ b/drivers/pci/msi/msi.c
+@@ -431,7 +431,7 @@ static int msi_capability_init(struct pc
+ struct irq_affinity *affd)
+ {
+ struct irq_affinity_desc *masks = NULL;
+- struct msi_desc *entry;
++ struct msi_desc *entry, desc;
+ int ret;
+
+ /*
+@@ -452,6 +452,12 @@ static int msi_capability_init(struct pc
+ /* All MSIs are unmasked by default; mask them all */
+ entry = msi_first_desc(&dev->dev, MSI_DESC_ALL);
+ pci_msi_mask(entry, msi_multi_mask(entry));
++ /*
++ * Copy the MSI descriptor for the error path because
++ * pci_msi_setup_msi_irqs() will free it for the hierarchical
++ * interrupt domain case.
++ */
++ memcpy(&desc, entry, sizeof(desc));
+
+ /* Configure MSI capability structure */
+ ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
+@@ -471,7 +477,7 @@ static int msi_capability_init(struct pc
+ goto unlock;
+
+ err:
+- pci_msi_unmask(entry, msi_multi_mask(entry));
++ pci_msi_unmask(&desc, msi_multi_mask(&desc));
+ free_msi_irqs(dev);
+ fail:
+ dev->msi_enabled = 0;
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- .../testing/selftests/net/mptcp/mptcp_join.sh | 21 ++++++++++++++-----
+ tools/testing/selftests/net/mptcp/mptcp_join.sh | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
-diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh
-index 0dbbc9e9ed6f6..e26da5f163154 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_join.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh
@@ -3285,11 +3285,12 @@ endpoint_tests()
fi
}
---
-2.43.0
-
selftests-mptcp-add-explicit-test-case-for-remove-re.patch
selftests-mptcp-join-check-re-using-id-of-unused-add.patch
selftests-mptcp-join-check-re-adding-init-endp-with-.patch
+pci-msi-fix-uaf-in-msi_capability_init.patch
+f2fs-fix-to-truncate-preallocated-blocks-in-f2fs_file_open.patch