Skip to content

[BUG REPORT] Unsound pointer arithmetic and unbounded loop in check_and_clone_cstr_array #1508

@DiuDiu777

Description

@DiuDiu777

描述错误

pub fn check_and_clone_cstr_array(user: *const *const u8) -> Result<Vec<CString>, SystemError> {
if user.is_null() {
Ok(Vec::new())
} else {
// debug!("check_and_clone_cstr_array: {:p}\n", user);
let mut buffer = Vec::new();
for i in 0.. {
let addr = unsafe { user.add(i) };
let str_ptr: *const u8;
// Read the value at this address (which is also a pointer)
unsafe {
let dst = [0usize; 1];
let mut dst = core::mem::transmute::<[usize; 1], [u8; size_of::<usize>()]>(dst);
// 使用受异常表保护的版本
copy_from_user_protected(&mut dst, VirtAddr::new(addr as usize))?;
let dst = core::mem::transmute::<[u8; size_of::<usize>()], [usize; 1]>(dst);
str_ptr = dst[0] as *const u8;
// debug!("str_ptr: {:p}, addr:{addr:?}\n", str_ptr);
}
if str_ptr.is_null() {
break;
}
// Read the string pointed to by this pointer
let string = check_and_clone_cstr(str_ptr, None)?;
// Put the string into the buffer
buffer.push(string);
}
return Ok(buffer);
}
}

(1) 潜在 DoS/OOM 风险:

目前的实现使用了 for i in 0.. 循环,似乎完全依赖用户传入的指针数组中包含 NULL 指针来作为终止条件。

但这里存在一个Unsound场景,就比如用户恶意传入一个构造好的、非常巨大的数组且不包含 NULL 结尾,这是否会导致内核在一个无限循环中不断分配内存?

(2) 指针算术的安全性:

场景同上。对于:

let addr = unsafe { user.add(i) };

ptr::add 要求计算后的结果指针必须仍在同一个“已分配对象”内(allocated object),且在 i 过大的时候会导致这个 add 结果溢出。

这里是否应该改用 wrapping_add 或者先转换为 usize 进行计算会更稳妥一些?

(3) 指针算术可能违反的 Safety Contract:

根据 Rust 标准库 pointer::add 的文档约束:

"The offset in bytes, count * size_of::<T>(), computed on mathematical integers (without “wrapping around”), must fit in an isize."

如果 count 来源于用户输入且数值较大,count * size_of::<*const u8>() 有可能超过 isize::MAX,从而直接违反 add 的 Safety Contract

请填写您的电脑的信息:

  • DragonOS版本hash:92895534f7c053abb5970491fca9af2cd002b5c1

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggood first issueGood for newcomers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions