rusticl: check for overrun status when deserializing
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32253>
(cherry picked from commit 813edb6cea
)
This commit is contained in:

committed by
Dylan Baker

parent
2cc0be2044
commit
c489be4522
@@ -954,7 +954,7 @@
|
|||||||
"description": "rusticl: check for overrun status when deserializing",
|
"description": "rusticl: check for overrun status when deserializing",
|
||||||
"nominated": true,
|
"nominated": true,
|
||||||
"nomination_type": 1,
|
"nomination_type": 1,
|
||||||
"resolution": 0,
|
"resolution": 1,
|
||||||
"main_sha": null,
|
"main_sha": null,
|
||||||
"because_sha": null,
|
"because_sha": null,
|
||||||
"notes": null
|
"notes": null
|
||||||
|
@@ -25,6 +25,7 @@ use std::convert::TryInto;
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
|
use std::ops::Not;
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
@@ -58,8 +59,10 @@ pub enum KernelArgType {
|
|||||||
|
|
||||||
impl KernelArgType {
|
impl KernelArgType {
|
||||||
fn deserialize(blob: &mut blob_reader) -> Option<Self> {
|
fn deserialize(blob: &mut blob_reader) -> Option<Self> {
|
||||||
Some(match unsafe { blob_read_uint8(blob) } {
|
// SAFETY: we get 0 on an overrun, but we verify that later and act accordingly.
|
||||||
|
let res = match unsafe { blob_read_uint8(blob) } {
|
||||||
0 => {
|
0 => {
|
||||||
|
// SAFETY: same here
|
||||||
let size = unsafe { blob_read_uint16(blob) };
|
let size = unsafe { blob_read_uint16(blob) };
|
||||||
KernelArgType::Constant(size)
|
KernelArgType::Constant(size)
|
||||||
}
|
}
|
||||||
@@ -71,7 +74,9 @@ impl KernelArgType {
|
|||||||
6 => KernelArgType::MemConstant,
|
6 => KernelArgType::MemConstant,
|
||||||
7 => KernelArgType::MemLocal,
|
7 => KernelArgType::MemLocal,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
})
|
};
|
||||||
|
|
||||||
|
blob.overrun.not().then_some(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize(&self, blob: &mut blob) {
|
fn serialize(&self, blob: &mut blob) {
|
||||||
@@ -192,13 +197,14 @@ impl KernelArg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(blob: &mut blob_reader) -> Option<Vec<Self>> {
|
fn deserialize(blob: &mut blob_reader) -> Option<Vec<Self>> {
|
||||||
unsafe {
|
// SAFETY: we check the overrun status, blob_read returns 0 in such a case.
|
||||||
let len = blob_read_uint16(blob) as usize;
|
let len = unsafe { blob_read_uint16(blob) } as usize;
|
||||||
let mut res = Vec::with_capacity(len);
|
let mut res = Vec::with_capacity(len);
|
||||||
|
|
||||||
for _ in 0..len {
|
for _ in 0..len {
|
||||||
let spirv = spirv::SPIRVKernelArg::deserialize(blob)?;
|
let spirv = spirv::SPIRVKernelArg::deserialize(blob)?;
|
||||||
let dead = blob_read_uint8(blob) != 0;
|
// SAFETY: we check the overrun status
|
||||||
|
let dead = unsafe { blob_read_uint8(blob) } != 0;
|
||||||
let kind = KernelArgType::deserialize(blob)?;
|
let kind = KernelArgType::deserialize(blob)?;
|
||||||
|
|
||||||
res.push(Self {
|
res.push(Self {
|
||||||
@@ -208,8 +214,7 @@ impl KernelArg {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(res)
|
blob.overrun.not().then_some(res)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1080,18 +1085,16 @@ impl SPIRVToNirResult {
|
|||||||
let args = KernelArg::deserialize(&mut reader)?;
|
let args = KernelArg::deserialize(&mut reader)?;
|
||||||
let default_build = CompilationResult::deserialize(&mut reader, d)?;
|
let default_build = CompilationResult::deserialize(&mut reader, d)?;
|
||||||
|
|
||||||
|
// SAFETY: on overrun this returns 0
|
||||||
let optimized = match unsafe { blob_read_uint8(&mut reader) } {
|
let optimized = match unsafe { blob_read_uint8(&mut reader) } {
|
||||||
0 => None,
|
0 => None,
|
||||||
_ => Some(CompilationResult::deserialize(&mut reader, d)?),
|
_ => Some(CompilationResult::deserialize(&mut reader, d)?),
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(SPIRVToNirResult::new(
|
reader
|
||||||
d,
|
.overrun
|
||||||
kernel_info,
|
.not()
|
||||||
args,
|
.then(|| SPIRVToNirResult::new(d, kernel_info, args, default_build, optimized))
|
||||||
default_build,
|
|
||||||
optimized,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// we can't use Self here as the nir shader might be compiled to a cso already and we can't
|
// we can't use Self here as the nir shader might be compiled to a cso already and we can't
|
||||||
|
@@ -9,6 +9,7 @@ use mesa_rust_util::string::*;
|
|||||||
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use std::ops::Not;
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
@@ -484,7 +485,8 @@ impl SPIRVKernelArg {
|
|||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(Self {
|
// check overrun to ensure nothing went wrong
|
||||||
|
blob.overrun.not().then(|| Self {
|
||||||
name: String::from_utf8_unchecked(name.to_owned()),
|
name: String::from_utf8_unchecked(name.to_owned()),
|
||||||
type_name: String::from_utf8_unchecked(type_name.to_owned()),
|
type_name: String::from_utf8_unchecked(type_name.to_owned()),
|
||||||
access_qualifier: clc_kernel_arg_access_qualifier(access_qualifier),
|
access_qualifier: clc_kernel_arg_access_qualifier(access_qualifier),
|
||||||
|
@@ -5,6 +5,7 @@ use mesa_rust_util::offset_of;
|
|||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use std::ops::Not;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
@@ -158,7 +159,9 @@ impl NirShader {
|
|||||||
blob: &mut blob_reader,
|
blob: &mut blob_reader,
|
||||||
options: *const nir_shader_compiler_options,
|
options: *const nir_shader_compiler_options,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
unsafe { Self::new(nir_deserialize(ptr::null_mut(), options, blob)) }
|
// we already create the NirShader here so it gets automatically deallocated on overrun.
|
||||||
|
let nir = Self::new(unsafe { nir_deserialize(ptr::null_mut(), options, blob) })?;
|
||||||
|
blob.overrun.not().then_some(nir)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize(&self, blob: &mut blob) {
|
pub fn serialize(&self, blob: &mut blob) {
|
||||||
|
Reference in New Issue
Block a user