Page MenuHomeFreeBSD

vm_fault: Fix a race in vm_fault_soft_fast()
ClosedPublic

Authored by markj on Feb 12 2023, 12:30 AM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Jun 24, 3:31 AM
Unknown Object (File)
Wed, Jun 19, 5:32 PM
Unknown Object (File)
Tue, Jun 18, 10:15 PM
Unknown Object (File)
Sat, Jun 15, 10:46 AM
Unknown Object (File)
Sat, Jun 15, 4:56 AM
Unknown Object (File)
Sat, Jun 15, 4:42 AM
Unknown Object (File)
Sat, Jun 15, 4:12 AM
Unknown Object (File)
Sat, Jun 15, 2:48 AM
Subscribers

Details

Summary

When vm_fault_soft_fast() creates a mapping, it release the VM map lock
before unbusying the top-level object. Without the map lock, however,
nothing prevents the VM object from being deallocated while still busy.

Fix the problem by unbusying the object before releasing the VM map
lock. In error cases the VM map lock is not released, so they don't
need to change.

Reported by: syzkaller

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

Should we assert obj->busy == 0 in vm_object_terminate()?

This revision is now accepted and ready to land.Feb 12 2023, 12:36 AM
In D38527#876480, @kib wrote:

Should we assert obj->busy == 0 in vm_object_terminate()?

vm_object_zdtor() already asserts this, I saw this panic from syzkaller:

panic: object 0xfffffe0096119000 busy = 1
cpuid = 0
time = 1676143223
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0xc7/frame 0xfffffe0093a6f330
kdb_backtrace() at kdb_backtrace+0xd3/frame 0xfffffe0093a6f490
vpanic() at vpanic+0x254/frame 0xfffffe0093a6f570
panic() at panic+0xb5/frame 0xfffffe0093a6f640
vm_object_zdtor() at vm_object_zdtor+0x242/frame 0xfffffe0093a6f670
uma_zfree_arg() at uma_zfree_arg+0x2d3/frame 0xfffffe0093a6f710
vm_object_deallocate() at vm_object_deallocate+0x649/frame 0xfffffe0093a6f800
vm_map_process_deferred() at vm_map_process_deferred+0x1b1/frame 0xfffffe0093a6f840
vm_map_fixed() at vm_map_fixed+0x235/frame 0xfffffe0093a6f8a0
vm_mmap_object() at vm_mmap_object+0x306/frame 0xfffffe0093a6f930
vn_mmap() at vn_mmap+0x488/frame 0xfffffe0093a6fab0
kern_mmap() at kern_mmap+0xf06/frame 0xfffffe0093a6fc50
sys_mmap() at sys_mmap+0x156/frame 0xfffffe0093a6fd50
amd64_syscall() at amd64_syscall+0x3d7/frame 0xfffffe0093a6ff30
fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0093a6ff30
--- syscall (198, FreeBSD ELF64, __syscall), rip = 0x2a8e8a, rsp = 0x82a3cdf08, rbp = 0x82a3cdf80 ---

It only happened once though, with no reproducer. So I am not certain that this patch is sufficient, but it seems likely so.

Simplify further: remove "res" and make the label name more accurate.

This revision now requires review to proceed.Feb 13 2023, 4:42 PM
This revision was not accepted when it landed; it landed in state Needs Review.Feb 13 2023, 9:36 PM
This revision was automatically updated to reflect the committed changes.