Skip to content

G.SAF.MEM.01 应校验内存申请函数的输入参数和返回值

【级别】 要求

【描述】

涉及内存分配的函数调用,应注意:

  • 申请前应校验申请大小

当申请内存大小由程序外部输入时,内存申请前,要求对申请内存大小进行合法性校验,防止申请 0 长度内存,或过多地、非法地申请内存。

  • 申请后应校验是否成功

当申请内存的数值过大(可能一次就申请了非常大的超预期的内存;也可能循环中多次申请内 存),可能会造成内存申请失败,返回空指针。

【反例】

申请前应校验申请大小

Rust
// CWE-789
fn get_untrusted_size() -> usize {
  //返回外部函数确定的大小
  unsafe { other_lib_get_size() } 
}

fn main() {
  let size = get_untrusted_size();
  // 不符合:内存分配 size 由外部传入,没有检查其值是否过大
  let buffer: Vec<u8> = Vec::with_capacity(size);
  // receive external data with buffer...
}

【正例】

申请前应校验申请大小

Rust
fn get_untrusted_size() -> usize {
  //返回外部函数确定的大小
  unsafe { other_lib_get_size() } 
}

fn main() {
  const BUF_MAX_SIZE: usize = 2_usize.pow(8);
  let size = BUF_MAX_SIZE.min(get_untrusted_size());
  // 符合:给外部传入的内存分配 size 值设定了一个上限
  let buffer: Vec<u8> = Vec::with_capacity(size);
  // receive external data with buffer...
}

【反例】

申请后应校验是否成功

Rust
fn func() {
  let malloc_size = || usize::MAX;
  // 不符合:未校验内存分配函数的参数
  let ptr = unsafe { libc::malloc(malloc_size()) };
  // 使用 ptr 进行内存操作 
  // ...
  unsafe { libc::free(ptr) }; 
}

【正例】

申请后应校验是否成功

Rust
fn func() {
  let malloc_size = || usize::MAX;
  let ptr = unsafe { libc::malloc(malloc_size()) }; 
  if !ptr.is_null() {
    // 使用 ptr 进行内存操作 
    // ...
    unsafe { libc::free(ptr) }; 
  }
}