Bug 1620488 Comment 0 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

If device-switching happens in a row, we may get the same UAF error in bug 1614971.

1. Start an _output_ cubeb stream _S_
2. Switch the output device, a device-changed callback is fired on the thread _C_ to dispatch the _stream-reinit_ task _R_ to the task queue _Q_ that runs on thread _T_
3. Destroy the cubeb stream _S_ on thread _A_, at the same time when _stream-reinit_ task _R_ is running on thread _T_
    1. The *device-changed* callbacks are not yet [unregisted](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L3305-L3325) for stream _S_ when _S_ is being destroyed, on the thread _A_
    2. The *device-changed* callbacks are not yet [registered](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L2824-L2838) for stream _S_, in the _stream-reinit_ task _R_ on thread _T_
4.  The _3-i_ is done first. The *device-changed* callbacks are [unregistered](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L3305-L3325) for stream _S_ on thread _A_
5. The _3-ii_ is done next. The *device-changed* callbacks are [registered](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L2824-L2838) for stream _S_, on thread _T_
6. The _stream-reinit_ task _R_ is done, while the stream destroy task _D_ is not
7. Switch the _output_ device again. Then the same error mentioned in bug 1614971 comment 3 and bug 1614971 comment 5 could show up again. Since the fix added in bug 1614971 [here](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L3305-L3325) doesn't work when _3-ii_ is done after _3-i_.
8. The *device-changed* callback is fired on the thread _C_
9. The stream is still being destroyed on thread _A_. It dispatches a stream-destroy task _D_ to the task queue _Q_
10. Just after the _stream-destroy_ task _D_ is pushed to the task queue _Q_, the *device-changed* callback on the thread _C_ pushes another _stream-reinit_ task _R'_ to the task queue _Q_.
11. The stream _S_ is destroyed after the _stream-destroy_ task _D_ is done.
12. Then task queue _Q_ will execute the _stream-reinit_ task _R'_. Then a _UAF_ error happens again since cubeb tries to reinitialize a destroyed stream _S_.


I don't fix the UAF caused by the data race properly in bug 1614971 (yah blame me). The fix there fixes the UAF error happens when switching the device once while the stream is being destroyed. If the device is switched in a row, in a few milliseconds, there is a slight chance to hit the same problem in bug 1614971 again. However, I doubt this can be done manually. I need to add some delays in a few places in the code to make it happen. 


This can be fixed in bug 1619005. Since all the tasks for stream _S_ appended after the stream-destroyed task for stream _S_ will be canceled.
If device-switching happens in a row, we may get the same UAF error in bug 1614971.

1. Start an _output_ cubeb stream _S_
2. Switch the output device, a device-changed callback is fired on the thread _C_ to dispatch the _stream-reinit_ task _R_ to the task queue _Q_ that runs on thread _T_
3. Destroy the cubeb stream _S_ on thread _A_, at the same time when _stream-reinit_ task _R_ is running on thread _T_
    1. The *device-changed* callbacks are not yet [unregisted](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L3305-L3325) for stream _S_ when _S_ is being destroyed, on the thread _A_
    2. The *device-changed* callbacks are not yet [registered](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L2824-L2838) for stream _S_, in the _stream-reinit_ task _R_ on thread _T_
4.  The _3-i_ is done first. The *device-changed* callbacks are [unregistered](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L3305-L3325) for stream _S_ on thread _A_
5. The _3-ii_ is done next. The *device-changed* callbacks are [registered](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L2824-L2838) for stream _S_, on thread _T_
6. The _stream-reinit_ task _R_ is done, while the stream destroy task _D_ is not
7. Switch the _output_ device again. Then the same error mentioned in bug 1614971 comment 3 and bug 1614971 comment 5 could show up again. Since the fix added in bug 1614971 [here](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L3305-L3325) doesn't work when _3-ii_ is done after _3-i_.
8. The *device-changed* callback is fired on the thread _C_
9. The stream is still being destroyed on thread _A_. It dispatches a stream-destroy task _D_ to the task queue _Q_
10. Just after the _stream-destroy_ task _D_ is pushed to the task queue _Q_, the *device-changed* callback on the thread _C_ pushes another _stream-reinit_ task _R'_ to the task queue _Q_.
11. The stream _S_ is destroyed after the _stream-destroy_ task _D_ is done.
12. Then task queue _Q_ will execute the _stream-reinit_ task _R'_. Then a _UAF_ error happens again since cubeb tries to reinitialize a destroyed stream _S_.


I didn't fix the UAF, caused by the data race, properly in bug 1614971 (yah blame me). The fix there fixes the UAF error happens when switching the device once while the stream is being destroyed. If the device is switched in a row, in a few milliseconds, there is a slight chance to hit the same problem in bug 1614971 again. However, I doubt this can be done manually. I need to add some delays in a few places in the code to make it happen. 


This can be fixed in bug 1619005. Since all the tasks for stream _S_ appended after the stream-destroyed task for stream _S_ will be canceled.
If device-switching happens in a row, we may get the same UAF error in bug 1614971.

1. Start an _output_ cubeb stream _S_
2. Switch the output device, a device-changed callback is fired on the thread _C_ to dispatch the _stream-reinit_ task _R_ to the task queue _Q_ that runs on thread _T_
3. Destroy the cubeb stream _S_ on thread _A_, at the same time when _stream-reinit_ task _R_ is running on thread _T_
    1. The *device-changed* callbacks are not yet [unregisted](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L3305-L3325) for stream _S_ when _S_ is being destroyed, on the thread _A_
    2. The *device-changed* callbacks are not yet [registered](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L2824-L2838) for stream _S_, in the _stream-reinit_ task _R_ on thread _T_
4.  The _3-i_ is done first. The *device-changed* callbacks are [unregistered](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L3305-L3325) for stream _S_ on thread _A_
5. The _3-ii_ is done next. The *device-changed* callbacks are [registered](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L2824-L2838) for stream _S_, on thread _T_
6. The _stream-reinit_ task _R_ is done, while the stream destroy task _D_ is not
7. Switch the _output_ device again. Then the same error mentioned in bug 1614971 comment 3 and bug 1614971 comment 5 could show up again. Since the fix added in bug 1614971 [here](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L3305-L3325) doesn't work when _3-ii_ is done after _3-i_.
8. The *device-changed* callback is fired on the thread _C_
9. The stream is still being destroyed on thread _A_. It dispatches a stream-destroy task _D_ to the task queue _Q_
10. Just after the _stream-destroy_ task _D_ is pushed to the task queue _Q_, the *device-changed* callback on the thread _C_ pushes another _stream-reinit_ task _R'_ to the task queue _Q_.
11. The stream _S_ is destroyed after the _stream-destroy_ task _D_ is done.
12. Then task queue _Q_ will execute the _stream-reinit_ task _R'_. Then a _UAF_ error happens again since cubeb tries to reinitialize a destroyed stream _S_.


I didn't fix the UAF, caused by the data race, properly in bug 1614971 (yah blame me). The fix there fixes the UAF error happens when switching the device while the stream is being destroyed. If the device is switched _in a row_, in a few milliseconds, there is a slight chance to hit the same problem in bug 1614971 again. However, I doubt this can be done manually. I need to add some delays in a few places in the code to make it happen. 


This can be fixed in bug 1619005. Since all the tasks for stream _S_ appended after the stream-destroyed task for stream _S_ will be canceled.
If device-switching happens in a row, we may get the same UAF error in bug 1614971.

1. Start an _output_ cubeb stream _S_
2. Switch the output device, a device-changed callback is fired on the thread _C_ to dispatch the _stream-reinit_ task _R_ to the task queue _Q_ that runs on thread _T_
3. Destroy the cubeb stream _S_ on thread _A_, at the same time when _stream-reinit_ task _R_ is running on thread _T_
    1. The *device-changed* callbacks are not yet [unregisted](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L3305-L3325) for stream _S_ when _S_ is being destroyed, on the thread _A_
    2. The *device-changed* callbacks are not yet [registered](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L2824-L2838) for stream _S_, in the _stream-reinit_ task _R_ on thread _T_
4.  The _3-i_ is done first. The *device-changed* callbacks are [unregistered](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L3305-L3325) for stream _S_ on thread _A_
5. The _3-ii_ is done next. The *device-changed* callbacks are [registered](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L2824-L2838) for stream _S_, on thread _T_
6. The _stream-reinit_ task _R_ is done, while the stream destroy task _D_ is not
7. Switch the _output_ device again. Then the same error mentioned in bug 1614971 comment 3 and bug 1614971 comment 5 could show up again. Since the fix added in bug 1614971 [here](https://github.com/ChunMinChang/cubeb-coreaudio-rs/blob/6fac4a62356ef4cec84e9e33b3692bcc1c1b1796/src/backend/mod.rs#L3305-L3325) doesn't work when _3-ii_ is done after _3-i_.
8. The *device-changed* callback is fired on the thread _C_
9. The stream is still being destroyed on thread _A_. It dispatches a stream-destroy task _D_ to the task queue _Q_
10. Just after the _stream-destroy_ task _D_ is pushed to the task queue _Q_, the *device-changed* callback on the thread _C_ pushes another _stream-reinit_ task _R'_ to the task queue _Q_.
11. The stream _S_ is destroyed after the _stream-destroy_ task _D_ is done.
12. Then task queue _Q_ will execute the _stream-reinit_ task _R'_. Then a _UAF_ error happens again since cubeb tries to reinitialize a destroyed stream _S_.


I didn't fix the UAF, caused by the data race, properly in bug 1614971 (yah blame me). The fix there fixes the UAF error happens when switching the device while the stream is being destroyed. If the device is switched _in a row_, in a few milliseconds, there is a slight chance to hit the same problem in bug 1614971 again. However, I guess it's nearly possible to do this manually. I need to add some delays in a few places in the code to make it happen. 


This can be fixed in bug 1619005. Since all the tasks for stream _S_ appended after the stream-destroyed task for stream _S_ will be canceled.

Back to Bug 1620488 Comment 0