UAF when destroying cubeb context while device collection is updating
Categories
(Core :: Audio/Video: cubeb, defect, P1)
Tracking
()
| Tracking | Status | |
|---|---|---|
| firefox-esr68 | --- | unaffected |
| firefox74 | --- | disabled |
| firefox75 | --- | wontfix |
| firefox76 | --- | fixed |
People
(Reporter: chunmin, Assigned: chunmin)
References
(Blocks 1 open bug)
Details
(Keywords: csectype-race, csectype-uaf, sec-high, Whiteboard: [post-critsmash-triage][adv-main76+r])
Found another UAF caused by data race when running Asan with cubeb-coreaudio @ 4816da8
In short, there are 2 threads that can be run in parallel, audio-thread A and device-collection-changed-callback task is being executed in task-thread T. When thread A runs AudioUnitContext::Drop at the same time when T is executing device-collection-changed-callback task, everything within cubeb context T touches may be destroyed.
LOG
==2628==ERROR: AddressSanitizer: heap-use-after-free on address 0x60d000037610 at pc 0x0001025e5453 bp 0x70000e03c5b0 sp 0x70000e03c5a8
READ of size 1 at 0x60d000037610 thread T158
#0 0x1025e5452 in core::sync::atomic::atomic_load::h061b6fe0721fd43b atomic.rs:2276
#1 0x10274f1eb in core::sync::atomic::AtomicBool::load::h4fc51bb8e0bbc47d atomic.rs:404
#2 0x102979268 in std::sys_common::poison::Flag::get::h98efa79c26adedb9 poison.rs:41
#3 0x102979433 in std::sys_common::poison::Flag::borrow::hd688b7cfa1b72de3 poison.rs:29
#4 0x102683faf in std::sync::mutex::MutexGuard$LT$T$GT$::new::hddebf96194100875 mutex.rs:419
#5 0x102682ffe in std::sync::mutex::Mutex$LT$T$GT$::lock::hab6b500925a26654 mutex.rs:219
#6 0x102861419 in cubeb_coreaudio::backend::audiounit_collection_changed_callback::_$u7b$$u7b$closure$u7d$$u7d$::he4d2311bba1c432f mod.rs:1708
#7 0x10289899e in coreaudio_sys_utils::dispatch::Queue::run_async::_$u7b$$u7b$closure$u7d$$u7d$::hd335c6c9e0ee93a2 dispatch.rs:34
#8 0x102894815 in coreaudio_sys_utils::dispatch::Queue::create_closure_and_executor::closure_executer::hd6ebd5a69f212a74 dispatch.rs:119
#9 0x10307d741 in asan_dispatch_call_block_and_release (librustc-nightly_rt.asan.dylib:x86_64h+0x43741)
#10 0x7fff6e81850d in _dispatch_client_callout (libdispatch.dylib:x86_64+0x350d)
#11 0x7fff6e81dacd in _dispatch_lane_serial_drain (libdispatch.dylib:x86_64+0x8acd)
#12 0x7fff6e81e451 in _dispatch_lane_invoke (libdispatch.dylib:x86_64+0x9451)
#13 0x7fff6e827a9d in _dispatch_workloop_worker_thread (libdispatch.dylib:x86_64+0x12a9d)
#14 0x7fff6ea726fb in _pthread_wqthread (libsystem_pthread.dylib:x86_64+0x26fb)
#15 0x7fff6ea71826 in start_wqthread (libsystem_pthread.dylib:x86_64+0x1826)
0x60d000037610 is located 48 bytes inside of 136-byte region [0x60d0000375e0,0x60d000037668)
freed by thread T144 here:
#0 0x10307edd6 in wrap_free (librustc-nightly_rt.asan.dylib:x86_64h+0x44dd6)
#1 0x10294b396 in alloc::alloc::dealloc::h7f52e4fb0a8ac0f2 alloc.rs:103
#2 0x10294ba57 in _$LT$alloc..alloc..Global$u20$as$u20$core..alloc..AllocRef$GT$::dealloc::ha109f847a76f3080 alloc.rs:174
#3 0x1029798dd in alloc::alloc::box_free::h0380f55f67ecd554 alloc.rs:223
#4 0x102b342ba in core::ptr::drop_in_place::h4dedd695f15bab0d mod.rs:177
#5 0x102784e0a in cubeb_backend::capi::capi_destroy::h8fd3f85b9ce3e834 capi.rs:133
#6 0x1025f84a8 in cubeb_coreaudio::backend::tests::utils::test_ops_context_operation::h67fa5a0df07af2ce utils.rs:1037
#7 0x1028aced7 in cubeb_coreaudio::backend::tests::interfaces::test_ops_context_register_device_collection_changed::h2a5a68e84133a06d interfaces.rs:267
#8 0x1029291e0 in cubeb_coreaudio::backend::tests::interfaces::test_ops_context_register_device_collection_changed::_$u7b$$u7b$closure$u7d$$u7d$::h4778057c519d64fc interfaces.rs:265
#9 0x102b27023 in core::ops::function::FnOnce::call_once::hcf3ef15c541b8d2b function.rs:232
#10 0x102b50d5d in _$LT$alloc..boxed..Box$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::h3e4927503aa0d3d2 boxed.rs:1017
#11 0x102c404fa in __rust_maybe_catch_panic lib.rs:86
#12 0x102b6aab1 in test::run_test::run_test_inner::_$u7b$$u7b$closure$u7d$$u7d$::h6cdbf3c39cd97641 lib.rs:542
#13 0x102b43cfa in std::sys_common::backtrace::__rust_begin_short_backtrace::hd3d992c394afe68a backtrace.rs:130
#14 0x102b48a8a in std::panicking::try::do_call::h9510f0857600c781 panicking.rs:303
#15 0x102c404fa in __rust_maybe_catch_panic lib.rs:86
#16 0x102b49685 in core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::heb23a0c73f6ef3d6 mod.rs:474
#17 0x102c2d9dd in _$LT$alloc..boxed..Box$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::hccc139f071572a3e boxed.rs:1017
#18 0x102c3fe2d in std::sys::unix::thread::Thread::new::thread_start::h8393670d384659c8 boxed.rs:1017
#19 0x7fff6ea75e64 in _pthread_start (libsystem_pthread.dylib:x86_64+0x5e64)
#20 0x7fff6ea7183a in thread_start (libsystem_pthread.dylib:x86_64+0x183a)
previously allocated by thread T144 here:
#0 0x10307ec8d in wrap_malloc (librustc-nightly_rt.asan.dylib:x86_64h+0x44c8d)
#1 0x10294b1f4 in alloc::alloc::alloc::ha80c734d14b65db0 alloc.rs:81
#2 0x10294b88d in _$LT$alloc..alloc..Global$u20$as$u20$core..alloc..AllocRef$GT$::alloc::hb5c760ebb2d750cd alloc.rs:169
#3 0x10294af73 in alloc::alloc::exchange_malloc::h1394c98163e0a55f alloc.rs:203
#4 0x1027e493c in _$LT$cubeb_coreaudio..backend..AudioUnitContext$u20$as$u20$cubeb_backend..traits..ContextOps$GT$::init::h9414da9de87f291e mod.rs:1993
#5 0x1027888ec in cubeb_backend::capi::capi_init::hc97f98f00179259b capi.rs:67
#6 0x1025f7c7f in cubeb_coreaudio::backend::tests::utils::test_ops_context_operation::h67fa5a0df07af2ce utils.rs:1032
#7 0x1028aced7 in cubeb_coreaudio::backend::tests::interfaces::test_ops_context_register_device_collection_changed::h2a5a68e84133a06d interfaces.rs:267
#8 0x1029291e0 in cubeb_coreaudio::backend::tests::interfaces::test_ops_context_register_device_collection_changed::_$u7b$$u7b$closure$u7d$$u7d$::h4778057c519d64fc interfaces.rs:265
#9 0x102b27023 in core::ops::function::FnOnce::call_once::hcf3ef15c541b8d2b function.rs:232
#10 0x102b50d5d in _$LT$alloc..boxed..Box$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::h3e4927503aa0d3d2 boxed.rs:1017
#11 0x102c404fa in __rust_maybe_catch_panic lib.rs:86
#12 0x102b6aab1 in test::run_test::run_test_inner::_$u7b$$u7b$closure$u7d$$u7d$::h6cdbf3c39cd97641 lib.rs:542
#13 0x102b43cfa in std::sys_common::backtrace::__rust_begin_short_backtrace::hd3d992c394afe68a backtrace.rs:130
#14 0x102b48a8a in std::panicking::try::do_call::h9510f0857600c781 panicking.rs:303
#15 0x102c404fa in __rust_maybe_catch_panic lib.rs:86
#16 0x102b49685 in core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::heb23a0c73f6ef3d6 mod.rs:474
#17 0x102c2d9dd in _$LT$alloc..boxed..Box$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::hccc139f071572a3e boxed.rs:1017
#18 0x102c3fe2d in std::sys::unix::thread::Thread::new::thread_start::h8393670d384659c8 boxed.rs:1017
#19 0x7fff6ea75e64 in _pthread_start (libsystem_pthread.dylib:x86_64+0x5e64)
#20 0x7fff6ea7183a in thread_start (libsystem_pthread.dylib:x86_64+0x183a)
Thread T158 created by T149 here:
<empty stack>
Thread T149 created by T0 here:
#0 0x103078dda in wrap_pthread_create (librustc-nightly_rt.asan.dylib:x86_64h+0x3edda)
#1 0x102c3fad7 in std::sys::unix::thread::Thread::new::h1b4dca91114b583e thread.rs:68
#2 0x102b6a42a in test::run_test::run_test_inner::h678171e02bf4fa8c mod.rs:492
#3 0x102b68a4d in test::run_test::h0dec6d766f0f894c lib.rs:506
#4 0x102b649ec in test::run_tests::hc2e4cbf21f87567c lib.rs:300
#5 0x102b56b15 in test::console::run_tests_console::h90212f32b3517c01 console.rs:280
#6 0x102b62112 in test::test_main::hdfe072594cd9fc2a lib.rs:121
#7 0x102b6311e in test::test_main_static::h3ab35108eccfecab lib.rs:140
#8 0x1028af367 in cubeb_coreaudio::main::hb57a761a62883121 (cubeb_coreaudio-0fc83ebf572ae290:x86_64+0x1002cc367)
#9 0x1028b05b9 in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h7bc9d6d6502f69e7 rt.rs:67
#10 0x102c39887 in std::panicking::try::do_call::h314555c7c658df7b panicking.rs:303
#11 0x102c404fa in __rust_maybe_catch_panic lib.rs:86
#12 0x102c3a179 in std::rt::lang_start_internal::h11f35f133c98e72a panicking.rs:281
#13 0x1028b051e in std::rt::lang_start::h243fbb9b5cc3408f rt.rs:67
#14 0x1028af391 in main (cubeb_coreaudio-0fc83ebf572ae290:x86_64+0x1002cc391)
#15 0x7fff6e8717fc in start (libdyld.dylib:x86_64+0x1a7fc)
Thread T144 created by T0 here:
#0 0x103078dda in wrap_pthread_create (librustc-nightly_rt.asan.dylib:x86_64h+0x3edda)
#1 0x102c3fad7 in std::sys::unix::thread::Thread::new::h1b4dca91114b583e thread.rs:68
#2 0x102b6a42a in test::run_test::run_test_inner::h678171e02bf4fa8c mod.rs:492
#3 0x102b68a4d in test::run_test::h0dec6d766f0f894c lib.rs:506
#4 0x102b649ec in test::run_tests::hc2e4cbf21f87567c lib.rs:300
#5 0x102b56b15 in test::console::run_tests_console::h90212f32b3517c01 console.rs:280
#6 0x102b62112 in test::test_main::hdfe072594cd9fc2a lib.rs:121
#7 0x102b6311e in test::test_main_static::h3ab35108eccfecab lib.rs:140
#8 0x1028af367 in cubeb_coreaudio::main::hb57a761a62883121 (cubeb_coreaudio-0fc83ebf572ae290:x86_64+0x1002cc367)
#9 0x1028b05b9 in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h7bc9d6d6502f69e7 rt.rs:67
#10 0x102c39887 in std::panicking::try::do_call::h314555c7c658df7b panicking.rs:303
#11 0x102c404fa in __rust_maybe_catch_panic lib.rs:86
#12 0x102c3a179 in std::rt::lang_start_internal::h11f35f133c98e72a panicking.rs:281
#13 0x1028b051e in std::rt::lang_start::h243fbb9b5cc3408f rt.rs:67
#14 0x1028af391 in main (cubeb_coreaudio-0fc83ebf572ae290:x86_64+0x1002cc391)
#15 0x7fff6e8717fc in start (libdyld.dylib:x86_64+0x1a7fc)
SUMMARY: AddressSanitizer: heap-use-after-free atomic.rs:2276 in core::sync::atomic::atomic_load::h061b6fe0721fd43b
Shadow bytes around the buggy address:
0x1c1a00006e70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c1a00006e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c1a00006e90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c1a00006ea0: fa fa fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x1c1a00006eb0: fd fd fd fa fa fa fa fa fa fa fa fa fd fd fd fd
=>0x1c1a00006ec0: fd fd[fd]fd fd fd fd fd fd fd fd fd fd fa fa fa
0x1c1a00006ed0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c1a00006ee0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c1a00006ef0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c1a00006f00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c1a00006f10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==2628==ABORTING
error: test failed, to rerun pass '--lib'
Caused by:
process didn't exit successfully: `/Users/cchang/Work/cubeb-coreaudio-rs/target/debug/deps/cubeb_coreaudio-0fc83ebf572ae290` (signal: 6, SIGABRT: process abort signal)
Finished test [unoptimized + debuginfo] target(s) in 0.03s
Running target/debug/deps/cubeb_coreaudio-0fc83ebf572ae290
| Assignee | ||
Comment 1•6 years ago
•
|
||
I didn't have a chance to try this in C backend, but C backend shouldn't hit this problem (but it can cause another UAF). The device-collection-changed-callback task won't be executed when the cubeb context is destroyed at the same time since they require to use the same mutex. However, the device-collection-changed-callback task might be appended to the task queue within cubeb context, which will be released asynchronously, after cubeb context is destroyed. This is also prone to lead to a UAF.
Updated•6 years ago
|
| Assignee | ||
Comment 2•6 years ago
|
||
The fix, cubeb-coreaudio-rs #55, is imported via D67536 in bug 1619005 comment 3. The commit message didn't mention anything about UAF. It merely says Destroy AudioUnitContext properly.
Updated•6 years ago
|
Comment 3•6 years ago
|
||
This should have gone through sec-approval, even if the end result is to land the fix under a cover bug, that way we can control the timing.
Do we need to fix this in 75? Is it safe enough to land directly in RC (from the other bug's description I would guess probably not)?
Comment 4•6 years ago
|
||
I guess https://bugzilla.mozilla.org/show_bug.cgi?id=1620488#c4 answers that.
Updated•6 years ago
|
Updated•5 years ago
|
Updated•5 years ago
|
Description
•