diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-04-23 06:17:27 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-04-23 06:17:27 -0700 |
commit | 47763fecbae29aac682e73f8cb21a5405af81327 (patch) | |
tree | e9d9e3f8107135f5749656c322d0da251d6ab3e8 | |
parent | de1118f3bb558c9199ae3a8c8e9313ecbccd1064 (diff) | |
download | stable-queue-47763fecbae29aac682e73f8cb21a5405af81327.tar.gz |
5.10-stable patches
added patches:
drm-amdgpu-validate-the-parameters-of-bo-mapping-operations-more-clearly.patch
nilfs2-fix-oob-in-nilfs_set_de_type.patch
nouveau-fix-instmem-race-condition-around-ptr-stores.patch
4 files changed, 293 insertions, 0 deletions
diff --git a/queue-5.10/drm-amdgpu-validate-the-parameters-of-bo-mapping-operations-more-clearly.patch b/queue-5.10/drm-amdgpu-validate-the-parameters-of-bo-mapping-operations-more-clearly.patch new file mode 100644 index 0000000000..9a3d82976f --- /dev/null +++ b/queue-5.10/drm-amdgpu-validate-the-parameters-of-bo-mapping-operations-more-clearly.patch @@ -0,0 +1,141 @@ +From 6fef2d4c00b5b8561ad68dd2b68173f5c6af1e75 Mon Sep 17 00:00:00 2001 +From: xinhui pan <xinhui.pan@amd.com> +Date: Thu, 11 Apr 2024 11:11:38 +0800 +Subject: drm/amdgpu: validate the parameters of bo mapping operations more clearly +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: xinhui pan <xinhui.pan@amd.com> + +commit 6fef2d4c00b5b8561ad68dd2b68173f5c6af1e75 upstream. + +Verify the parameters of +amdgpu_vm_bo_(map/replace_map/clearing_mappings) in one common place. + +Fixes: dc54d3d1744d ("drm/amdgpu: implement AMDGPU_VA_OP_CLEAR v2") +Cc: stable@vger.kernel.org +Reported-by: Vlad Stolyarov <hexed@google.com> +Suggested-by: Christian König <christian.koenig@amd.com> +Signed-off-by: xinhui pan <xinhui.pan@amd.com> +Reviewed-by: Christian König <christian.koenig@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 72 +++++++++++++++++++++------------ + 1 file changed, 46 insertions(+), 26 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +@@ -2201,6 +2201,37 @@ static void amdgpu_vm_bo_insert_map(stru + trace_amdgpu_vm_bo_map(bo_va, mapping); + } + ++/* Validate operation parameters to prevent potential abuse */ ++static int amdgpu_vm_verify_parameters(struct amdgpu_device *adev, ++ struct amdgpu_bo *bo, ++ uint64_t saddr, ++ uint64_t offset, ++ uint64_t size) ++{ ++ uint64_t tmp, lpfn; ++ ++ if (saddr & AMDGPU_GPU_PAGE_MASK ++ || offset & AMDGPU_GPU_PAGE_MASK ++ || size & AMDGPU_GPU_PAGE_MASK) ++ return -EINVAL; ++ ++ if (check_add_overflow(saddr, size, &tmp) ++ || check_add_overflow(offset, size, &tmp) ++ || size == 0 /* which also leads to end < begin */) ++ return -EINVAL; ++ ++ /* make sure object fit at this offset */ ++ if (bo && offset + size > amdgpu_bo_size(bo)) ++ return -EINVAL; ++ ++ /* Ensure last pfn not exceed max_pfn */ ++ lpfn = (saddr + size - 1) >> AMDGPU_GPU_PAGE_SHIFT; ++ if (lpfn >= adev->vm_manager.max_pfn) ++ return -EINVAL; ++ ++ return 0; ++} ++ + /** + * amdgpu_vm_bo_map - map bo inside a vm + * +@@ -2227,21 +2258,14 @@ int amdgpu_vm_bo_map(struct amdgpu_devic + struct amdgpu_bo *bo = bo_va->base.bo; + struct amdgpu_vm *vm = bo_va->base.vm; + uint64_t eaddr; ++ int r; + +- /* validate the parameters */ +- if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK) +- return -EINVAL; +- if (saddr + size <= saddr || offset + size <= offset) +- return -EINVAL; +- +- /* make sure object fit at this offset */ +- eaddr = saddr + size - 1; +- if ((bo && offset + size > amdgpu_bo_size(bo)) || +- (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT)) +- return -EINVAL; ++ r = amdgpu_vm_verify_parameters(adev, bo, saddr, offset, size); ++ if (r) ++ return r; + + saddr /= AMDGPU_GPU_PAGE_SIZE; +- eaddr /= AMDGPU_GPU_PAGE_SIZE; ++ eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE; + + tmp = amdgpu_vm_it_iter_first(&vm->va, saddr, eaddr); + if (tmp) { +@@ -2294,17 +2318,9 @@ int amdgpu_vm_bo_replace_map(struct amdg + uint64_t eaddr; + int r; + +- /* validate the parameters */ +- if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK) +- return -EINVAL; +- if (saddr + size <= saddr || offset + size <= offset) +- return -EINVAL; +- +- /* make sure object fit at this offset */ +- eaddr = saddr + size - 1; +- if ((bo && offset + size > amdgpu_bo_size(bo)) || +- (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT)) +- return -EINVAL; ++ r = amdgpu_vm_verify_parameters(adev, bo, saddr, offset, size); ++ if (r) ++ return r; + + /* Allocate all the needed memory */ + mapping = kmalloc(sizeof(*mapping), GFP_KERNEL); +@@ -2318,7 +2334,7 @@ int amdgpu_vm_bo_replace_map(struct amdg + } + + saddr /= AMDGPU_GPU_PAGE_SIZE; +- eaddr /= AMDGPU_GPU_PAGE_SIZE; ++ eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE; + + mapping->start = saddr; + mapping->last = eaddr; +@@ -2405,10 +2421,14 @@ int amdgpu_vm_bo_clear_mappings(struct a + struct amdgpu_bo_va_mapping *before, *after, *tmp, *next; + LIST_HEAD(removed); + uint64_t eaddr; ++ int r; ++ ++ r = amdgpu_vm_verify_parameters(adev, NULL, saddr, 0, size); ++ if (r) ++ return r; + +- eaddr = saddr + size - 1; + saddr /= AMDGPU_GPU_PAGE_SIZE; +- eaddr /= AMDGPU_GPU_PAGE_SIZE; ++ eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE; + + /* Allocate all the needed memory */ + before = kzalloc(sizeof(*before), GFP_KERNEL); diff --git a/queue-5.10/nilfs2-fix-oob-in-nilfs_set_de_type.patch b/queue-5.10/nilfs2-fix-oob-in-nilfs_set_de_type.patch new file mode 100644 index 0000000000..f463678c28 --- /dev/null +++ b/queue-5.10/nilfs2-fix-oob-in-nilfs_set_de_type.patch @@ -0,0 +1,53 @@ +From c4a7dc9523b59b3e73fd522c73e95e072f876b16 Mon Sep 17 00:00:00 2001 +From: Jeongjun Park <aha310510@gmail.com> +Date: Tue, 16 Apr 2024 03:20:48 +0900 +Subject: nilfs2: fix OOB in nilfs_set_de_type + +From: Jeongjun Park <aha310510@gmail.com> + +commit c4a7dc9523b59b3e73fd522c73e95e072f876b16 upstream. + +The size of the nilfs_type_by_mode array in the fs/nilfs2/dir.c file is +defined as "S_IFMT >> S_SHIFT", but the nilfs_set_de_type() function, +which uses this array, specifies the index to read from the array in the +same way as "(mode & S_IFMT) >> S_SHIFT". + +static void nilfs_set_de_type(struct nilfs_dir_entry *de, struct inode + *inode) +{ + umode_t mode = inode->i_mode; + + de->file_type = nilfs_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; // oob +} + +However, when the index is determined this way, an out-of-bounds (OOB) +error occurs by referring to an index that is 1 larger than the array size +when the condition "mode & S_IFMT == S_IFMT" is satisfied. Therefore, a +patch to resize the nilfs_type_by_mode array should be applied to prevent +OOB errors. + +Link: https://lkml.kernel.org/r/20240415182048.7144-1-konishi.ryusuke@gmail.com +Reported-by: syzbot+2e22057de05b9f3b30d8@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=2e22057de05b9f3b30d8 +Fixes: 2ba466d74ed7 ("nilfs2: directory entry operations") +Signed-off-by: Jeongjun Park <aha310510@gmail.com> +Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com> +Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com> +Cc: <stable@vger.kernel.org> +Signed-off-by: Andrew Morton <akpm@linux-foundation.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + fs/nilfs2/dir.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nilfs2/dir.c ++++ b/fs/nilfs2/dir.c +@@ -243,7 +243,7 @@ nilfs_filetype_table[NILFS_FT_MAX] = { + + #define S_SHIFT 12 + static unsigned char +-nilfs_type_by_mode[S_IFMT >> S_SHIFT] = { ++nilfs_type_by_mode[(S_IFMT >> S_SHIFT) + 1] = { + [S_IFREG >> S_SHIFT] = NILFS_FT_REG_FILE, + [S_IFDIR >> S_SHIFT] = NILFS_FT_DIR, + [S_IFCHR >> S_SHIFT] = NILFS_FT_CHRDEV, diff --git a/queue-5.10/nouveau-fix-instmem-race-condition-around-ptr-stores.patch b/queue-5.10/nouveau-fix-instmem-race-condition-around-ptr-stores.patch new file mode 100644 index 0000000000..7760cb3a1d --- /dev/null +++ b/queue-5.10/nouveau-fix-instmem-race-condition-around-ptr-stores.patch @@ -0,0 +1,96 @@ +From fff1386cc889d8fb4089d285f883f8cba62d82ce Mon Sep 17 00:00:00 2001 +From: Dave Airlie <airlied@redhat.com> +Date: Thu, 11 Apr 2024 11:15:09 +1000 +Subject: nouveau: fix instmem race condition around ptr stores + +From: Dave Airlie <airlied@redhat.com> + +commit fff1386cc889d8fb4089d285f883f8cba62d82ce upstream. + +Running a lot of VK CTS in parallel against nouveau, once every +few hours you might see something like this crash. + +BUG: kernel NULL pointer dereference, address: 0000000000000008 +PGD 8000000114e6e067 P4D 8000000114e6e067 PUD 109046067 PMD 0 +Oops: 0000 [#1] PREEMPT SMP PTI +CPU: 7 PID: 53891 Comm: deqp-vk Not tainted 6.8.0-rc6+ #27 +Hardware name: Gigabyte Technology Co., Ltd. Z390 I AORUS PRO WIFI/Z390 I AORUS PRO WIFI-CF, BIOS F8 11/05/2021 +RIP: 0010:gp100_vmm_pgt_mem+0xe3/0x180 [nouveau] +Code: c7 48 01 c8 49 89 45 58 85 d2 0f 84 95 00 00 00 41 0f b7 46 12 49 8b 7e 08 89 da 42 8d 2c f8 48 8b 47 08 41 83 c7 01 48 89 ee <48> 8b 40 08 ff d0 0f 1f 00 49 8b 7e 08 48 89 d9 48 8d 75 04 48 c1 +RSP: 0000:ffffac20c5857838 EFLAGS: 00010202 +RAX: 0000000000000000 RBX: 00000000004d8001 RCX: 0000000000000001 +RDX: 00000000004d8001 RSI: 00000000000006d8 RDI: ffffa07afe332180 +RBP: 00000000000006d8 R08: ffffac20c5857ad0 R09: 0000000000ffff10 +R10: 0000000000000001 R11: ffffa07af27e2de0 R12: 000000000000001c +R13: ffffac20c5857ad0 R14: ffffa07a96fe9040 R15: 000000000000001c +FS: 00007fe395eed7c0(0000) GS:ffffa07e2c980000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000000008 CR3: 000000011febe001 CR4: 00000000003706f0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + +... + + ? gp100_vmm_pgt_mem+0xe3/0x180 [nouveau] + ? gp100_vmm_pgt_mem+0x37/0x180 [nouveau] + nvkm_vmm_iter+0x351/0xa20 [nouveau] + ? __pfx_nvkm_vmm_ref_ptes+0x10/0x10 [nouveau] + ? __pfx_gp100_vmm_pgt_mem+0x10/0x10 [nouveau] + ? __pfx_gp100_vmm_pgt_mem+0x10/0x10 [nouveau] + ? __lock_acquire+0x3ed/0x2170 + ? __pfx_gp100_vmm_pgt_mem+0x10/0x10 [nouveau] + nvkm_vmm_ptes_get_map+0xc2/0x100 [nouveau] + ? __pfx_nvkm_vmm_ref_ptes+0x10/0x10 [nouveau] + ? __pfx_gp100_vmm_pgt_mem+0x10/0x10 [nouveau] + nvkm_vmm_map_locked+0x224/0x3a0 [nouveau] + +Adding any sort of useful debug usually makes it go away, so I hand +wrote the function in a line, and debugged the asm. + +Every so often pt->memory->ptrs is NULL. This ptrs ptr is set in +the nv50_instobj_acquire called from nvkm_kmap. + +If Thread A and Thread B both get to nv50_instobj_acquire around +the same time, and Thread A hits the refcount_set line, and in +lockstep thread B succeeds at refcount_inc_not_zero, there is a +chance the ptrs value won't have been stored since refcount_set +is unordered. Force a memory barrier here, I picked smp_mb, since +we want it on all CPUs and it's write followed by a read. + +v2: use paired smp_rmb/smp_wmb. + +Cc: <stable@vger.kernel.org> +Fixes: be55287aa5ba ("drm/nouveau/imem/nv50: embed nvkm_instobj directly into nv04_instobj") +Signed-off-by: Dave Airlie <airlied@redhat.com> +Signed-off-by: Danilo Krummrich <dakr@redhat.com> +Link: https://patchwork.freedesktop.org/patch/msgid/20240411011510.2546857-1-airlied@gmail.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +@@ -221,8 +221,11 @@ nv50_instobj_acquire(struct nvkm_memory + void __iomem *map = NULL; + + /* Already mapped? */ +- if (refcount_inc_not_zero(&iobj->maps)) ++ if (refcount_inc_not_zero(&iobj->maps)) { ++ /* read barrier match the wmb on refcount set */ ++ smp_rmb(); + return iobj->map; ++ } + + /* Take the lock, and re-check that another thread hasn't + * already mapped the object in the meantime. +@@ -249,6 +252,8 @@ nv50_instobj_acquire(struct nvkm_memory + iobj->base.memory.ptrs = &nv50_instobj_fast; + else + iobj->base.memory.ptrs = &nv50_instobj_slow; ++ /* barrier to ensure the ptrs are written before refcount is set */ ++ smp_wmb(); + refcount_set(&iobj->maps, 1); + } + diff --git a/queue-5.10/series b/queue-5.10/series index 5a92b2f7d6..3d66cd7300 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -67,3 +67,6 @@ mei-me-disable-rpl-s-on-sps-and-ign-firmwares.patch speakup-avoid-crash-on-very-long-word.patch fs-sysfs-fix-reference-leak-in-sysfs_break_active_protection.patch init-main.c-fix-potential-static_command_line-memory-overflow.patch +drm-amdgpu-validate-the-parameters-of-bo-mapping-operations-more-clearly.patch +nouveau-fix-instmem-race-condition-around-ptr-stores.patch +nilfs2-fix-oob-in-nilfs_set_de_type.patch |