mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-28 04:45:05 +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]
|
#[test]
|
||||||
fn recursive_adt() {
|
fn recursive_adt() {
|
||||||
check_answer(
|
check_fail(
|
||||||
r#"
|
r#"
|
||||||
//- minicore: coerce_unsized, index, slice
|
//- minicore: coerce_unsized, index, slice
|
||||||
pub enum TagTree {
|
pub enum TagTree {
|
||||||
|
@ -2849,6 +2849,6 @@ fn recursive_adt() {
|
||||||
TAG_TREE
|
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"),
|
ConstScalar::Unknown => not_supported!("evaluating unknown const"),
|
||||||
};
|
};
|
||||||
let patch_map = memory_map.transform_addresses(|b, mut align| {
|
let patch_map = memory_map.transform_addresses(|b, 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 addr = self.heap_allocate(b.len(), align)?;
|
let addr = self.heap_allocate(b.len(), align)?;
|
||||||
self.write_memory(addr, b)?;
|
self.write_memory(addr, b)?;
|
||||||
Ok(addr.to_usize())
|
Ok(addr.to_usize())
|
||||||
|
@ -1938,7 +1931,11 @@ impl Evaluator<'_> {
|
||||||
ty: &Ty,
|
ty: &Ty,
|
||||||
locals: &Locals,
|
locals: &Locals,
|
||||||
mm: &mut ComplexMemoryMap,
|
mm: &mut ComplexMemoryMap,
|
||||||
|
stack_depth_limit: usize,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
if stack_depth_limit.checked_sub(1).is_none() {
|
||||||
|
return Err(MirEvalError::StackOverflow);
|
||||||
|
}
|
||||||
match ty.kind(Interner) {
|
match ty.kind(Interner) {
|
||||||
TyKind::Ref(_, _, t) => {
|
TyKind::Ref(_, _, t) => {
|
||||||
let size = this.size_align_of(t, locals)?;
|
let size = this.size_align_of(t, locals)?;
|
||||||
|
@ -1977,7 +1974,14 @@ impl Evaluator<'_> {
|
||||||
if let Some(ty) = check_inner {
|
if let Some(ty) = check_inner {
|
||||||
for i in 0..count {
|
for i in 0..count {
|
||||||
let offset = element_size * i;
|
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")?;
|
let size = this.size_of_sized(inner, locals, "inner of array")?;
|
||||||
for i in 0..len {
|
for i in 0..len {
|
||||||
let offset = i * size;
|
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) => {
|
chalk_ir::TyKind::Tuple(_, subst) => {
|
||||||
|
@ -2000,7 +2011,14 @@ impl Evaluator<'_> {
|
||||||
let ty = ty.assert_ty_ref(Interner); // Tuple only has type argument
|
let ty = ty.assert_ty_ref(Interner); // Tuple only has type argument
|
||||||
let offset = layout.fields.offset(id).bytes_usize();
|
let offset = layout.fields.offset(id).bytes_usize();
|
||||||
let size = this.layout(ty)?.size.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 {
|
chalk_ir::TyKind::Adt(adt, subst) => match adt.0 {
|
||||||
|
@ -2015,7 +2033,14 @@ impl Evaluator<'_> {
|
||||||
.bytes_usize();
|
.bytes_usize();
|
||||||
let ty = &field_types[f].clone().substitute(Interner, subst);
|
let ty = &field_types[f].clone().substitute(Interner, subst);
|
||||||
let size = this.layout(ty)?.size.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,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AdtId::EnumId(e) => {
|
AdtId::EnumId(e) => {
|
||||||
|
@ -2034,7 +2059,14 @@ impl Evaluator<'_> {
|
||||||
l.fields.offset(u32::from(f.into_raw()) as usize).bytes_usize();
|
l.fields.offset(u32::from(f.into_raw()) as usize).bytes_usize();
|
||||||
let ty = &field_types[f].clone().substitute(Interner, subst);
|
let ty = &field_types[f].clone().substitute(Interner, subst);
|
||||||
let size = this.layout(ty)?.size.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,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2045,7 +2077,7 @@ impl Evaluator<'_> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
let mut mm = ComplexMemoryMap::default();
|
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)
|
Ok(mm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue