Skip to content

Commit 8a42e14

Browse files
committed
fs: fuse/virtio_fs: Fix kernel null pointer dereference
BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 2.535283] #PF: supervisor write access in kernel mode [ 2.535769] #PF: error_code(0x0002) - not-present page [ 2.536395] PGD 107b37067 P4D 107b37067 PUD 107b38067 PMD 0 [ 2.537158] Oops: Oops: 0002 [#1] SMP NOPTI [ 2.537802] CPU: 4 UID: 0 PID: 152 Comm: WSLGd Not tainted 6.17.0-rc4-WSL2+ torvalds#59 PREEMPT(none) [ 2.539416] RIP: 0010:virtio_fs_direct_access+0x6f/0xa0 [ 2.540356] Code: 00 00 48 01 c6 49 89 75 00 48 85 ed 74 0e 48 8b b1 88 00 00 00 48 01 c6 48 89 75 00 48 03 81 88 00 00 00 48 c1 e8 0c 48 39 d3 <48> 89 45 00 48 89 d0 48 0f 46 c3 5b 5d 41 5c 41 5d 31 d2 31 c9 31 [ 2.543093] RSP: 0018:ffffbdf8c2ec7c08 EFLAGS: 00010206 [ 2.543647] RAX: 0000000000a00000 RBX: 000fffffffffffff RCX: ffff9f6e91171f00 [ 2.544456] RDX: 0000000000200000 RSI: 0000000000000000 RDI: 000000000000000c [ 2.545348] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 [ 2.546233] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 [ 2.547036] R13: 0000000000000000 R14: ffff9f6e82d8ab00 R15: ffff9f6e84152480 [ 2.547878] FS: 000075fe7e256800(0000) GS:ffff9f71c0968000(0000) knlGS:0000000000000000 [ 2.548814] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 2.549730] CR2: 0000000000000000 CR3: 0000000107b2f000 CR4: 0000000000350ef0 [ 2.550750] Call Trace: [ 2.551031] <TASK> [ 2.551418] dax_direct_access+0x35/0xc0 [ 2.551993] fuse_dax_conn_alloc+0x118/0x2e0 [ 2.552660] fuse_fill_super_common+0xf1/0x440 [ 2.553436] ? __kmalloc_cache_noprof+0x149/0x410 [ 2.554110] ? fuse_dev_alloc+0x7d/0x100 [ 2.554925] ? shrinker_register+0x8c/0xb0 [ 2.555349] virtio_fs_get_tree+0x35b/0x460 [ 2.555850] vfs_get_tree+0x29/0xe0 [ 2.556203] path_mount+0x582/0xac0 [ 2.556953] __x64_sys_mount+0x11d/0x150 [ 2.557786] do_syscall_64+0x72/0xb00 [ 2.559436] ? do_syscall_64+0x72/0xb00 [ 2.559818] ? do_syscall_64+0x72/0xb00 [ 2.560449] ? exc_page_fault+0x69/0x150 [ 2.560719] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 2.561167] RIP: 0033:0x75fe80ca92ce [ 2.561720] Code: 48 8b 0d 4d 3b 0e 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 1a 3b 0e 00 f7 d8 64 89 01 48 [ 2.563792] RSP: 002b:00007ffd31c720a8 EFLAGS: 00000246 ORIG_RAX: 00000000000000a5 [ 2.564707] RAX: ffffffffffffffda RBX: 00007ffd31c72138 RCX: 000075fe80ca92ce [ 2.565596] RDX: 000000000040d48f RSI: 000000000040d47c RDI: 000000000040d74a [ 2.566431] RBP: 00007ffd31c73f5b R08: 000000000040d498 R09: 0000000000000000 [ 2.567439] R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffd31c73e43 [ 2.568466] R13: 00007ffd31c73fc3 R14: 000075fe80d95500 R15: 000075fe7e256770 [ 2.569408] </TASK> [ 2.569755] Modules linked in: [ 2.570124] CR2: 0000000000000000 [ 2.570532] ---[ end trace 0000000000000000 ]--- [ 2.571164] RIP: 0010:virtio_fs_direct_access+0x6f/0xa0 [ 2.571860] Code: 00 00 48 01 c6 49 89 75 00 48 85 ed 74 0e 48 8b b1 88 00 00 00 48 01 c6 48 89 75 00 48 03 81 88 00 00 00 48 c1 e8 0c 48 39 d3 <48> 89 45 00 48 89 d0 48 0f 46 c3 5b 5d 41 5c 41 5d 31 d2 31 c9 31 [ 2.574309] RSP: 0018:ffffbdf8c2ec7c08 EFLAGS: 00010206 [ 2.575423] RAX: 0000000000a00000 RBX: 000fffffffffffff RCX: ffff9f6e91171f00 [ 2.576827] RDX: 0000000000200000 RSI: 0000000000000000 RDI: 000000000000000c [ 2.577479] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000 [ 2.578149] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 [ 2.578825] R13: 0000000000000000 R14: ffff9f6e82d8ab00 R15: ffff9f6e84152480 [ 2.579618] FS: 000075fe7e256800(0000) GS:ffff9f71c0968000(0000) knlGS:0000000000000000 [ 2.580636] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 2.581196] CR2: 0000000000000000 CR3: 0000000107b2f000 CR4: 0000000000350ef0 [ 2.582207] Kernel panic - not syncing: Fatal exception
1 parent 12b2972 commit 8a42e14

File tree

1 file changed

+5
-6
lines changed

1 file changed

+5
-6
lines changed

fs/fuse/virtio_fs.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include <linux/pci.h>
1010
#include <linux/interrupt.h>
1111
#include <linux/group_cpus.h>
12-
#include <linux/pfn_t.h>
1312
#include <linux/memremap.h>
1413
#include <linux/module.h>
1514
#include <linux/virtio.h>
@@ -862,7 +861,7 @@ static void virtio_fs_requests_done_work(struct work_struct *work)
862861
static void virtio_fs_map_queues(struct virtio_device *vdev, struct virtio_fs *fs)
863862
{
864863
const struct cpumask *mask, *masks;
865-
unsigned int q, cpu;
864+
unsigned int q, cpu, nr_masks;
866865

867866
/* First attempt to map using existing transport layer affinities
868867
* e.g. PCIe MSI-X
@@ -882,7 +881,7 @@ static void virtio_fs_map_queues(struct virtio_device *vdev, struct virtio_fs *f
882881
return;
883882
fallback:
884883
/* Attempt to map evenly in groups over the CPUs */
885-
masks = group_cpus_evenly(fs->num_request_queues);
884+
masks = group_cpus_evenly(fs->num_request_queues, &nr_masks);
886885
/* If even this fails we default to all CPUs use first request queue */
887886
if (!masks) {
888887
for_each_possible_cpu(cpu)
@@ -891,7 +890,7 @@ static void virtio_fs_map_queues(struct virtio_device *vdev, struct virtio_fs *f
891890
}
892891

893892
for (q = 0; q < fs->num_request_queues; q++) {
894-
for_each_cpu(cpu, &masks[q])
893+
for_each_cpu(cpu, &masks[q % nr_masks])
895894
fs->mq_map[cpu] = q + VQ_REQUEST;
896895
}
897896
kfree(masks);
@@ -1008,7 +1007,7 @@ static void virtio_fs_cleanup_vqs(struct virtio_device *vdev)
10081007
*/
10091008
static long virtio_fs_direct_access(struct dax_device *dax_dev, pgoff_t pgoff,
10101009
long nr_pages, enum dax_access_mode mode,
1011-
void **kaddr, pfn_t *pfn)
1010+
void **kaddr, unsigned long *pfn)
10121011
{
10131012
struct virtio_fs *fs = dax_get_private(dax_dev);
10141013
phys_addr_t offset = PFN_PHYS(pgoff);
@@ -1017,7 +1016,7 @@ static long virtio_fs_direct_access(struct dax_device *dax_dev, pgoff_t pgoff,
10171016
if (kaddr)
10181017
*kaddr = fs->window_kaddr + offset;
10191018
if (pfn)
1020-
*pfn = phys_to_pfn_t(fs->window_phys_addr + offset, 0);
1019+
*pfn = PHYS_PFN(fs->window_phys_addr + offset);
10211020
return nr_pages > max_nr_pages ? max_nr_pages : nr_pages;
10221021
}
10231022

0 commit comments

Comments
 (0)