media: ffmpeg: Add 'static bounds to AvBuffer::new.

The previous signature allowed lifetime laundering if code like below
was used:

impl<'a> AvBufferSource for &'a mut [u8] { ... }

fn foo() {
    let mut storage = vec![];
    let buf = AvBuffer::new(storage.deref_mut());
    drop(storage);
    // buf can be used after free
}

Add a 'static bound to prevent it.

BUG=None
TEST=cargo build --release --features "video-decoder,ffmpeg" -p devices

Change-Id: Ifda2793a3e3d4d8b400fa076f1d6f9474d0ae159
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3833771
Reviewed-by: Junichi Uekawa <uekawa@chromium.org>
Reviewed-by: Alexandre Courbot <acourbot@chromium.org>
Commit-Queue: Tatsuyuki Ishi <ishitatsuyuki@google.com>
Tested-by: Tatsuyuki Ishi <ishitatsuyuki@google.com>
This commit is contained in:
Tatsuyuki Ishi 2022-08-12 10:26:47 +09:00 committed by crosvm LUCI
parent 39ad7ce5d6
commit 7fcbd8e9e1

View file

@ -415,7 +415,7 @@ impl AvBuffer {
/// references to this buffer reaches zero.
///
/// Returns `None` if the buffer could not be created due to an error in libavcodec.
fn new<D: AvBufferSource>(source: D) -> Option<Self> {
fn new<D: AvBufferSource + 'static>(source: D) -> Option<Self> {
// Move storage to the heap so we find it at the same place in `avbuffer_free`
let mut storage = Box::new(source);
@ -425,8 +425,8 @@ impl AvBuffer {
let _ = unsafe { Box::from_raw(opaque as *mut D) };
}
// Safe because storage points to valid data and we are checking the return value against
// NULL, which signals an error.
// Safe because storage points to valid data throughout the lifetime of AVBuffer and we are
// checking the return value against NULL, which signals an error.
Some(Self(unsafe {
ffi::av_buffer_create(
storage.as_mut_ptr(),
@ -510,7 +510,10 @@ impl<'a> AvPacket<'a> {
///
/// The returned `AvPacket` will have a `'static` lifetime and will keep `input_data` alive for
/// as long as libavcodec needs it.
pub fn new_owned<T: AvBufferSource>(pts: i64, input_data: T) -> Result<Self, AvPacketError> {
pub fn new_owned<T: AvBufferSource + 'static>(
pts: i64,
input_data: T,
) -> Result<Self, AvPacketError> {
let mut av_buffer =
AvBuffer::new(input_data).ok_or(AvPacketError::AvBufferCreationError)?;
let data_slice = av_buffer.as_mut_slice();