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:
Karol Herbst
2024-11-19 02:20:38 +01:00
committed by Dylan Baker
parent 2cc0be2044
commit c489be4522
4 changed files with 35 additions and 27 deletions

View File

@@ -954,7 +954,7 @@
"description": "rusticl: check for overrun status when deserializing",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null,
"notes": null

View File

@@ -25,6 +25,7 @@ use std::convert::TryInto;
use std::fmt::Debug;
use std::fmt::Display;
use std::ops::Index;
use std::ops::Not;
use std::os::raw::c_void;
use std::ptr;
use std::slice;
@@ -58,8 +59,10 @@ pub enum KernelArgType {
impl KernelArgType {
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 => {
// SAFETY: same here
let size = unsafe { blob_read_uint16(blob) };
KernelArgType::Constant(size)
}
@@ -71,7 +74,9 @@ impl KernelArgType {
6 => KernelArgType::MemConstant,
7 => KernelArgType::MemLocal,
_ => return None,
})
};
blob.overrun.not().then_some(res)
}
fn serialize(&self, blob: &mut blob) {
@@ -192,13 +197,14 @@ impl KernelArg {
}
fn deserialize(blob: &mut blob_reader) -> Option<Vec<Self>> {
unsafe {
let len = blob_read_uint16(blob) as usize;
// SAFETY: we check the overrun status, blob_read returns 0 in such a case.
let len = unsafe { blob_read_uint16(blob) } as usize;
let mut res = Vec::with_capacity(len);
for _ in 0..len {
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)?;
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 default_build = CompilationResult::deserialize(&mut reader, d)?;
// SAFETY: on overrun this returns 0
let optimized = match unsafe { blob_read_uint8(&mut reader) } {
0 => None,
_ => Some(CompilationResult::deserialize(&mut reader, d)?),
};
Some(SPIRVToNirResult::new(
d,
kernel_info,
args,
default_build,
optimized,
))
reader
.overrun
.not()
.then(|| SPIRVToNirResult::new(d, kernel_info, args, default_build, optimized))
}
// we can't use Self here as the nir shader might be compiled to a cso already and we can't

View File

@@ -9,6 +9,7 @@ use mesa_rust_util::string::*;
use std::ffi::CString;
use std::fmt::Debug;
use std::ops::Not;
use std::os::raw::c_char;
use std::os::raw::c_void;
use std::ptr;
@@ -484,7 +485,8 @@ impl SPIRVKernelArg {
_ => return None,
};
Some(Self {
// check overrun to ensure nothing went wrong
blob.overrun.not().then(|| Self {
name: String::from_utf8_unchecked(name.to_owned()),
type_name: String::from_utf8_unchecked(type_name.to_owned()),
access_qualifier: clc_kernel_arg_access_qualifier(access_qualifier),

View File

@@ -5,6 +5,7 @@ use mesa_rust_util::offset_of;
use std::convert::TryInto;
use std::ffi::CString;
use std::marker::PhantomData;
use std::ops::Not;
use std::ptr;
use std::ptr::NonNull;
use std::slice;
@@ -158,7 +159,9 @@ impl NirShader {
blob: &mut blob_reader,
options: *const nir_shader_compiler_options,
) -> 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) {