mirror of
https://github.com/github/codeql.git
synced 2026-04-24 00:05:14 +02:00
Rust: Add a test for uncontrolled allocation size.
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
query: queries/security/CWE-770/UncontrolledAllocationSize.ql
|
||||
postprocess:
|
||||
- utils/test/InlineExpectationsTestQuery.ql
|
||||
- utils/test/PrettyPrintModels.ql
|
||||
223
rust/ql/test/query-tests/security/CWE-770/main.rs
Normal file
223
rust/ql/test/query-tests/security/CWE-770/main.rs
Normal file
@@ -0,0 +1,223 @@
|
||||
#![feature(alloc_layout_extra)]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(try_with_capacity)]
|
||||
#![feature(box_vec_non_null)]
|
||||
#![feature(non_null_from_ref)]
|
||||
|
||||
struct MyStruct {
|
||||
_a: usize,
|
||||
_b: i64,
|
||||
}
|
||||
|
||||
unsafe fn test_std_alloc_from_size(v: usize) {
|
||||
let l1 = std::alloc::Layout::from_size_align(16, 1).unwrap();
|
||||
let m1 = std::alloc::alloc(l1);
|
||||
let _ = std::alloc::alloc(l1.align_to(8).unwrap());
|
||||
let _ = std::alloc::alloc(l1.align_to(8).unwrap().pad_to_align());
|
||||
let _ = std::alloc::alloc_zeroed(l1);
|
||||
let _ = std::alloc::realloc(m1, l1, v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let l2 = std::alloc::Layout::from_size_align(v, 1).unwrap();
|
||||
let _ = std::alloc::alloc(l2); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = std::alloc::alloc(l2.align_to(8).unwrap()); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = std::alloc::alloc(l2.align_to(8).unwrap().pad_to_align()); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = std::alloc::alloc_zeroed(l2); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let l3 = std::alloc::Layout::from_size_align(1, v).unwrap(); // not obviously dangerous?
|
||||
let _ = std::alloc::alloc(l3);
|
||||
|
||||
let l4 = std::alloc::Layout::from_size_align_unchecked(v, 1);
|
||||
let _ = std::alloc::alloc(l4); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let l5 = std::alloc::Layout::from_size_align_unchecked(v * std::mem::size_of::<i64>(), std::mem::size_of::<i64>());
|
||||
let _ = std::alloc::alloc(l5); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let s6 = (std::mem::size_of::<MyStruct>() * v) + 1;
|
||||
let l6 = std::alloc::Layout::from_size_align_unchecked(s6, 4);
|
||||
let _ = std::alloc::alloc(l6); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let l7 = std::alloc::Layout::from_size_align_unchecked(l6.size(), 8);
|
||||
let _ = std::alloc::alloc(l7); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
}
|
||||
|
||||
unsafe fn test_std_alloc_new_repeat_extend(v: usize) {
|
||||
let l1 = std::alloc::Layout::new::<[u8; 10]>();
|
||||
let _ = std::alloc::alloc(l1);
|
||||
|
||||
let l2 = std::alloc::Layout::new::<MyStruct>();
|
||||
let _ = std::alloc::alloc(l2);
|
||||
let _ = std::alloc::alloc(l2.repeat(10).unwrap().0);
|
||||
let _ = std::alloc::alloc(l2.repeat(v).unwrap().0); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = std::alloc::alloc(l2.repeat(v + 1).unwrap().0); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = std::alloc::alloc(l2.repeat_packed(10).unwrap());
|
||||
let _ = std::alloc::alloc(l2.repeat_packed(v).unwrap()); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = std::alloc::alloc(l2.repeat_packed(v * 10).unwrap()); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let l3 = std::alloc::Layout::array::<u8>(10).unwrap();
|
||||
let _ = std::alloc::alloc(l3);
|
||||
let (k1, _offs1) = l3.repeat(v).expect("arithmetic overflow?");
|
||||
let _ = std::alloc::alloc(k1); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let (k2, _offs2) = l3.extend(k1).unwrap();
|
||||
let _ = std::alloc::alloc(k2); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let (k3, _offs3) = k1.extend(l3).unwrap();
|
||||
let _ = std::alloc::alloc(k3); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = std::alloc::alloc(l3.extend_packed(k1).unwrap()); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = std::alloc::alloc(k1.extend_packed(l3).unwrap()); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let l4 = std::alloc::Layout::array::<u8>(v).unwrap();
|
||||
let _ = std::alloc::alloc(l4); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
}
|
||||
|
||||
fn clamp<T: std::cmp::PartialOrd>(v: T, min: T, max: T) -> T {
|
||||
if v < min {
|
||||
return min;
|
||||
} else if v > max {
|
||||
return max;
|
||||
} else {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn test_std_alloc_with_bounds(v: usize) {
|
||||
let l1 = std::alloc::Layout::array::<u32>(v).unwrap();
|
||||
|
||||
if v < 100 {
|
||||
let _ = std::alloc::alloc(l1);
|
||||
} else {
|
||||
let _ = std::alloc::alloc(l1); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
}
|
||||
|
||||
if v == 100 {
|
||||
let _ = std::alloc::alloc(l1);
|
||||
} else {
|
||||
let _ = std::alloc::alloc(l1); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
}
|
||||
|
||||
{
|
||||
let mut v_mut = v;
|
||||
|
||||
if v_mut > 100 {
|
||||
v_mut = 100;
|
||||
}
|
||||
|
||||
let l2 = std::alloc::Layout::array::<u32>(v_mut).unwrap();
|
||||
let _ = std::alloc::alloc(l2);
|
||||
|
||||
let l3 = std::alloc::Layout::array::<u32>(v).unwrap();
|
||||
let _ = std::alloc::alloc(l3); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
}
|
||||
|
||||
let l4 = std::alloc::Layout::array::<u32>(std::cmp::min(v, 100)).unwrap();
|
||||
let _ = std::alloc::alloc(l4);
|
||||
|
||||
let l5 = std::alloc::Layout::array::<u32>(std::cmp::max(v, 100)).unwrap();
|
||||
let _ = std::alloc::alloc(l5); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let l6 = std::alloc::Layout::array::<u32>(clamp(v, 1, 100)).unwrap();
|
||||
let _ = std::alloc::alloc(l6);
|
||||
|
||||
let _ = std::alloc::alloc(l1); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
if v > 100 {
|
||||
return;
|
||||
}
|
||||
let _ = std::alloc::alloc(l1);
|
||||
}
|
||||
|
||||
use std::alloc::{GlobalAlloc, Allocator};
|
||||
|
||||
unsafe fn test_system_alloc(v: usize) {
|
||||
let l1 = std::alloc::Layout::array::<u8>(10).unwrap();
|
||||
let _ = std::alloc::System.alloc(l1);
|
||||
let _ = std::alloc::System.alloc_zeroed(l1);
|
||||
let _ = std::alloc::System.allocate(l1).unwrap();
|
||||
let _ = std::alloc::System.allocate_zeroed(l1).unwrap();
|
||||
let _ = std::alloc::Global.allocate(l1).unwrap();
|
||||
let _ = std::alloc::Global.allocate_zeroed(l1).unwrap();
|
||||
|
||||
let l2 = std::alloc::Layout::array::<u8>(v).unwrap();
|
||||
let _ = std::alloc::System.alloc(l2); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = std::alloc::System.alloc_zeroed(l2); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = std::alloc::System.allocate(l2).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = std::alloc::System.allocate_zeroed(l2).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = std::alloc::Global.allocate(l2).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = std::alloc::Global.allocate_zeroed(l2).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let l3 = std::alloc::Layout::array::<u8>(10).unwrap();
|
||||
let m3 = std::alloc::System.alloc(l3);
|
||||
let _ = std::alloc::System.realloc(m3, l3, v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let l4 = std::alloc::Layout::array::<u8>(10).unwrap();
|
||||
let m4 = std::ptr::NonNull::<u8>::new(std::alloc::alloc(l4)).unwrap();
|
||||
if v > 10 {
|
||||
if v % 2 == 0 {
|
||||
let _ = std::alloc::System.grow(m4, l4, l2).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
} else {
|
||||
let _ = std::alloc::System.grow_zeroed(m4, l4, l2).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
}
|
||||
} else {
|
||||
let _ = std::alloc::System.shrink(m4, l4, l2).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn test_libc_alloc(v: usize) {
|
||||
let m1 = libc::malloc(256);
|
||||
let _ = libc::malloc(v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = libc::aligned_alloc(8, v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = libc::aligned_alloc(v, 8);
|
||||
let _ = libc::calloc(64, v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = libc::calloc(v, std::mem::size_of::<i64>()); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = libc::realloc(m1, v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
}
|
||||
|
||||
unsafe fn test_vectors(v: usize) {
|
||||
let _ = Vec::<u64>::try_with_capacity(v).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = Vec::<u64>::with_capacity(v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = Vec::<u64>::try_with_capacity_in(v, std::alloc::Global).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = Vec::<u64>::with_capacity_in(v, std::alloc::Global); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let mut v1 = Vec::<u64>::with_capacity(100);
|
||||
v1.reserve(v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
v1.reserve_exact(v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = v1.try_reserve(v).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
let _ = v1.try_reserve_exact(v).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
v1.resize(v, 1); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
v1.set_len(v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let l2 = std::alloc::Layout::new::<[u64; 200]>();
|
||||
let m2 = std::ptr::NonNull::<u64>::new(std::alloc::alloc(l2).cast::<u64>()).unwrap();
|
||||
let _ = Vec::<u64>::from_parts(m2, v, 200); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let m3 = std::ptr::NonNull::<u64>::new(std::alloc::alloc(l2).cast::<u64>()).unwrap();
|
||||
let _ = Vec::<u64>::from_parts(m3, 100, v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let m4 = std::ptr::NonNull::<u64>::new(std::alloc::alloc(l2).cast::<u64>()).unwrap();
|
||||
let _ = Vec::<u64>::from_parts_in(m4, 100, v, std::alloc::Global); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let m5 = std::alloc::alloc(l2).cast::<u64>();
|
||||
let _ = Vec::<u64>::from_raw_parts(m5, v, 200); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let m6 = std::alloc::alloc(l2).cast::<u64>();
|
||||
let _ = Vec::<u64>::from_raw_parts(m6, 100, v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
|
||||
let m7 = std::alloc::alloc(l2).cast::<u64>();
|
||||
let _ = Vec::<u64>::from_raw_parts_in(m7, 100, v, std::alloc::Global); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
|
||||
}
|
||||
|
||||
// --- main ---
|
||||
|
||||
fn main() {
|
||||
println!("--- begin ---");
|
||||
|
||||
let v = std::env::args().nth(1).unwrap_or("1024".to_string()).parse::<usize>().unwrap(); // $ Source=arg1
|
||||
|
||||
unsafe {
|
||||
test_std_alloc_from_size(v);
|
||||
test_std_alloc_new_repeat_extend(v);
|
||||
test_std_alloc_with_bounds(v);
|
||||
test_system_alloc(v);
|
||||
test_libc_alloc(v);
|
||||
test_vectors(v);
|
||||
}
|
||||
|
||||
println!("--- end ---");
|
||||
}
|
||||
3
rust/ql/test/query-tests/security/CWE-770/options.yml
Normal file
3
rust/ql/test/query-tests/security/CWE-770/options.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
qltest_cargo_check: true
|
||||
qltest_dependencies:
|
||||
- libc = { version = "0.2.11" }
|
||||
@@ -0,0 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2025-03-17"
|
||||
Reference in New Issue
Block a user