DragonOS icon indicating copy to clipboard operation
DragonOS copied to clipboard

[BUG REPORT] Integer overflow in `page_align_up`

Open Marsman1996 opened this issue 1 year ago • 11 comments

描述错误/Describe the bug There is an integer overflow in page_align_up() at kernel/src/libs/align.rs:135 when program calls memory related syscall (i.e., mmap, munmap, and mprotect) with large len.

https://github.com/DragonOS-Community/DragonOS/blob/72423f90bb39a9a3919b3630857785653c97d36c/kernel/src/libs/align.rs#L133-L136

请填写您的电脑的信息/Environment

  • OS Version:Debian GNU/Linux 11
  • DragonOS Version:72423f9
  • DADK Version:dadk 0.2.0
  • Rust Version:rustc 1.84.0-nightly (fbab78289 2024-11-04)

重现步骤/To Reproduce

  1. Compile a program which calls system call munmap with large len
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

int main() {
  void *addr = mmap(NULL, 0x1000, 0x3, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  munmap(addr, 0xffffffffffffffff);
  perror("mmap error");

  return EXIT_SUCCESS;
}

  1. Run the compiled program

期望行为/Expected behavior DragonOS should check the add behavior first and not overflow here.

屏幕截图/Log I add log before and after the alignment:

root@DragonOS:/$ /bin/overflow
[ WARN ] (src/syscall/mod.rs:626)        len before align: 0xffffffffffffffff
[ WARN ] (src/syscall/mod.rs:628)        len after align: 0x0
mmap error: Invalid argument

Marsman1996 avatar Dec 11 '24 07:12 Marsman1996

I'm trying to add check for overflow in kernel/Cargo.toml, but after adding the check I cannot enter the DragonOS.

我尝试在 kernel/Cargo.toml 中增加对 overflow 的检查,但是这样编译后无法正常进入系统:

# The release profile, used for `cargo build --release`
[profile.release]
debug = false
overflow-checks = true

Marsman1996 avatar Dec 11 '24 07:12 Marsman1996

cc @MemoryShore @Jomocool 麻烦看看~

fslongjin avatar Dec 11 '24 07:12 fslongjin

但是这个貌似也是正常?Linux上面传入过大的len的话,会返回什么? @Marsman1996

fslongjin avatar Dec 11 '24 07:12 fslongjin

但是这个貌似也是正常?Linux上面传入过大的len的话,会返回什么? @Marsman1996

munmap 为例,会返回 EINVAL https://elixir.bootlin.com/linux/v6.10.5/source/mm/mmap.c#L2738

但是在 Rust 程序中,这样的溢出在 debug 模式下会导致 panic。 不过 DragonOS 似乎写死了就以 release 编译👀 kernel/src/Makefile

kernel_rust:
	RUSTFLAGS="$(RUSTFLAGS)" cargo +nightly-2024-11-05 $(CARGO_ZBUILD) build --release --target $(TARGET_JSON)

Marsman1996 avatar Dec 11 '24 07:12 Marsman1996

这里可以考虑在内核里面加个判断啥的,实现行为上跟Linux一致? 你方便发个pr吗 @Marsman1996

fslongjin avatar Dec 11 '24 07:12 fslongjin

这里可以考虑在内核里面加个判断啥的,实现行为上跟Linux一致? 你方便发个pr吗 @Marsman1996

👌

Marsman1996 avatar Dec 11 '24 08:12 Marsman1996

我没太理解,按照上面你所描述的,dragonos不也是返回了EINVAL吗? @Marsman1996

fslongjin avatar Jan 01 '25 07:01 fslongjin

我没太理解,按照上面你所描述的,dragonos不也是返回了EINVAL吗? @Marsman1996

dragonos现在是直接返回usize吧

MemoryShore avatar Jan 01 '25 09:01 MemoryShore

我没太理解,按照上面你所描述的,dragonos不也是返回了EINVAL吗? @Marsman1996

dragonos 在 align 溢出后返回 len 的值为 0x0,而在 munmaplen 做检查,会在 len == 0x0 时对系统返回 EINVAL

https://github.com/DragonOS-Community/DragonOS/blob/e92424df8d2ee08d0800ea9f9f7fd3e23434243d/kernel/src/mm/syscall.rs#L457-L459

也就是说虽然 dragonos 目前也是返回的 EINVAL,但是溢出已经发生了

Marsman1996 avatar Jan 01 '25 15:01 Marsman1996

我没太理解,按照上面你所描述的,dragonos不也是返回了EINVAL吗? @Marsman1996

dragonos 在 align 溢出后返回 len 的值为 0x0,而在 munmaplen 做检查,会在 len == 0x0 时对系统返回 EINVAL

https://github.com/DragonOS-Community/DragonOS/blob/e92424df8d2ee08d0800ea9f9f7fd3e23434243d/kernel/src/mm/syscall.rs#L457-L459

也就是说虽然 dragonos 目前也是返回的 EINVAL,但是溢出已经发生了

那么, 在 https://github.com/DragonOS-Community/DragonOS/pull/1078 的修改后,貌似这个地方就不会返回EINVAL了。这样貌似不对?

fslongjin avatar Jan 01 '25 15:01 fslongjin

我没太理解,按照上面你所描述的,dragonos不也是返回了EINVAL吗? @Marsman1996

dragonos 在 align 溢出后返回 len 的值为 0x0,而在 munmaplen 做检查,会在 len == 0x0 时对系统返回 EINVAL https://github.com/DragonOS-Community/DragonOS/blob/e92424df8d2ee08d0800ea9f9f7fd3e23434243d/kernel/src/mm/syscall.rs#L457-L459

也就是说虽然 dragonos 目前也是返回的 EINVAL,但是溢出已经发生了

那么, 在 #1078 的修改后,貌似这个地方就不会返回EINVAL了。这样貌似不对?

使用 wrapping_add 后,page_align_up

addr.wrapping_add(page_size - 1) & (!(page_size - 1))

在溢出时返回值依然是 0x0 所以还是会在上文提到的位置返回 EINVAL

Marsman1996 avatar Jan 02 '25 02:01 Marsman1996