mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 14:13:58 +00:00
fix: Check stack depth to prevent stack overflows in create_memory_map
This commit is contained in:
parent
7c1be82cd9
commit
142ef764ee
2 changed files with 48 additions and 16 deletions
|
@ -2828,7 +2828,7 @@ fn unsized_local() {
|
|||
|
||||
#[test]
|
||||
fn recursive_adt() {
|
||||
check_answer(
|
||||
check_fail(
|
||||
r#"
|
||||
//- minicore: coerce_unsized, index, slice
|
||||
pub enum TagTree {
|
||||
|
@ -2849,6 +2849,6 @@ fn recursive_adt() {
|
|||
TAG_TREE
|
||||
};
|
||||
"#,
|
||||
|b, _| assert_eq!(b[0] % 8, 0),
|
||||
|e| matches!(e, ConstEvalError::MirEvalError(MirEvalError::StackOverflow)),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1710,14 +1710,7 @@ impl Evaluator<'_> {
|
|||
}
|
||||
ConstScalar::Unknown => not_supported!("evaluating unknown const"),
|
||||
};
|
||||
let patch_map = memory_map.transform_addresses(|b, mut align| {
|
||||
// Prevent recursive addresses is adts and slices
|
||||
match ((&b[..b.len() / 2]).try_into(), HEAP_OFFSET.checked_add(align)) {
|
||||
(Ok(arr), Some(new_addr)) if usize::from_le_bytes(arr) == new_addr => {
|
||||
align *= 2;
|
||||
}
|
||||
_ => (),
|
||||
};
|
||||
let patch_map = memory_map.transform_addresses(|b, align| {
|
||||
let addr = self.heap_allocate(b.len(), align)?;
|
||||
self.write_memory(addr, b)?;
|
||||
Ok(addr.to_usize())
|
||||
|
@ -1938,7 +1931,11 @@ impl Evaluator<'_> {
|
|||
ty: &Ty,
|
||||
locals: &Locals,
|
||||
mm: &mut ComplexMemoryMap,
|
||||
stack_depth_limit: usize,
|
||||
) -> Result<()> {
|
||||
if stack_depth_limit.checked_sub(1).is_none() {
|
||||
return Err(MirEvalError::StackOverflow);
|
||||
}
|
||||
match ty.kind(Interner) {
|
||||
TyKind::Ref(_, _, t) => {
|
||||
let size = this.size_align_of(t, locals)?;
|
||||
|
@ -1977,7 +1974,14 @@ impl Evaluator<'_> {
|
|||
if let Some(ty) = check_inner {
|
||||
for i in 0..count {
|
||||
let offset = element_size * i;
|
||||
rec(this, &b[offset..offset + element_size], ty, locals, mm)?;
|
||||
rec(
|
||||
this,
|
||||
&b[offset..offset + element_size],
|
||||
ty,
|
||||
locals,
|
||||
mm,
|
||||
stack_depth_limit - 1,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1991,7 +1995,14 @@ impl Evaluator<'_> {
|
|||
let size = this.size_of_sized(inner, locals, "inner of array")?;
|
||||
for i in 0..len {
|
||||
let offset = i * size;
|
||||
rec(this, &bytes[offset..offset + size], inner, locals, mm)?;
|
||||
rec(
|
||||
this,
|
||||
&bytes[offset..offset + size],
|
||||
inner,
|
||||
locals,
|
||||
mm,
|
||||
stack_depth_limit - 1,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
chalk_ir::TyKind::Tuple(_, subst) => {
|
||||
|
@ -2000,7 +2011,14 @@ impl Evaluator<'_> {
|
|||
let ty = ty.assert_ty_ref(Interner); // Tuple only has type argument
|
||||
let offset = layout.fields.offset(id).bytes_usize();
|
||||
let size = this.layout(ty)?.size.bytes_usize();
|
||||
rec(this, &bytes[offset..offset + size], ty, locals, mm)?;
|
||||
rec(
|
||||
this,
|
||||
&bytes[offset..offset + size],
|
||||
ty,
|
||||
locals,
|
||||
mm,
|
||||
stack_depth_limit - 1,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
chalk_ir::TyKind::Adt(adt, subst) => match adt.0 {
|
||||
|
@ -2015,7 +2033,14 @@ impl Evaluator<'_> {
|
|||
.bytes_usize();
|
||||
let ty = &field_types[f].clone().substitute(Interner, subst);
|
||||
let size = this.layout(ty)?.size.bytes_usize();
|
||||
rec(this, &bytes[offset..offset + size], ty, locals, mm)?;
|
||||
rec(
|
||||
this,
|
||||
&bytes[offset..offset + size],
|
||||
ty,
|
||||
locals,
|
||||
mm,
|
||||
stack_depth_limit - 1,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
AdtId::EnumId(e) => {
|
||||
|
@ -2034,7 +2059,14 @@ impl Evaluator<'_> {
|
|||
l.fields.offset(u32::from(f.into_raw()) as usize).bytes_usize();
|
||||
let ty = &field_types[f].clone().substitute(Interner, subst);
|
||||
let size = this.layout(ty)?.size.bytes_usize();
|
||||
rec(this, &bytes[offset..offset + size], ty, locals, mm)?;
|
||||
rec(
|
||||
this,
|
||||
&bytes[offset..offset + size],
|
||||
ty,
|
||||
locals,
|
||||
mm,
|
||||
stack_depth_limit - 1,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2045,7 +2077,7 @@ impl Evaluator<'_> {
|
|||
Ok(())
|
||||
}
|
||||
let mut mm = ComplexMemoryMap::default();
|
||||
rec(self, bytes, ty, locals, &mut mm)?;
|
||||
rec(self, bytes, ty, locals, &mut mm, self.stack_depth_limit - 1)?;
|
||||
Ok(mm)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue