audio: fix device name use-after-free in AudioDevice::open

Fixes a use-after-free in `AudioDevice::open`, which occurs when
selecting a particular device by name (as opposed to using a default
device).

Specifically, when extracting a C-style string pointer from a
`Option<CString>`, the option was consumed, its contents turned into a
pointer, and the original `CString` dropped. After that the C-style
string pointer is dangling, as its backing rust CString has been freed.

To fix this, the CString must be kept alive, which is achieved by simply
creating an intermediary `Option<&CString>`, and consuming that.
This commit is contained in:
Gautier Minster
2020-06-23 15:21:18 -07:00
parent 92fb34da8f
commit f7370be3a3
+4 -1
View File
@@ -652,7 +652,10 @@ impl<CB: AudioCallback> AudioDevice<CB> {
Some(device) => Some(CString::new(device).unwrap()),
None => None
};
let device_ptr = device.map_or(ptr::null(), |s| s.as_ptr());
// Warning: map_or consumes its argument; `device.map_or()` would therefore consume the
// CString and drop it, making device_ptr a dangling pointer! To avoid that we downgrade
// device to an Option<&_> first.
let device_ptr = device.as_ref().map_or(ptr::null(), |s| s.as_ptr());
let iscapture_flag = if capture { 1 } else { 0 };
let device_id = sys::SDL_OpenAudioDevice(