-
Notifications
You must be signed in to change notification settings - Fork 0
feat: musl libc full support - syscalls, env, pthread, epoll, and test programs #230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -133,6 +133,8 @@ pub enum FdKind { | |
| ProcfsFile { content: alloc::string::String, position: usize }, | ||
| /// Procfs directory listing (for /proc and /proc/[pid]) | ||
| ProcfsDirectory { path: alloc::string::String, position: u64 }, | ||
| /// Epoll instance file descriptor | ||
| Epoll(u64), | ||
| } | ||
|
|
||
| impl core::fmt::Debug for FdKind { | ||
|
|
@@ -168,6 +170,7 @@ impl core::fmt::Debug for FdKind { | |
| FdKind::FifoWrite(path, _) => write!(f, "FifoWrite({})", path), | ||
| FdKind::ProcfsFile { content, position } => write!(f, "ProcfsFile(len={}, pos={})", content.len(), position), | ||
| FdKind::ProcfsDirectory { path, position } => write!(f, "ProcfsDirectory(path={}, pos={})", path, position), | ||
| FdKind::Epoll(id) => write!(f, "Epoll({})", id), | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -735,6 +738,10 @@ impl Drop for FdTable { | |
| FdKind::ProcfsDirectory { .. } => { | ||
| // Procfs directory doesn't need cleanup | ||
| } | ||
| FdKind::Epoll(id) => { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Epoll instance leaked during exec close_cloexec cleanupMedium Severity When |
||
| // Clean up the epoll instance | ||
| crate::syscall::epoll::remove_instance(id); | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Epoll instance removed prematurely after forkMedium Severity
Additional Locations (1) |
||
| } | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -584,11 +584,19 @@ impl ProcessManager { | |
|
|
||
| // Set up argc/argv/envp/auxv on the stack following Linux ABI | ||
| // The stack is now mapped, so we can write to it via physical addresses | ||
| let default_env: [&[u8]; 5] = [ | ||
| b"PATH=/bin:/sbin\0", | ||
| b"HOME=/\0", | ||
| b"TERM=vt100\0", | ||
| b"USER=root\0", | ||
| b"SHELL=/bin/bsh\0", | ||
| ]; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Triplicated default_env array across process creation pathsLow Severity The identical Additional Locations (2) |
||
| let initial_sp = if let Some(ref page_table) = process.page_table { | ||
| self.setup_argv_on_stack( | ||
| page_table, | ||
| user_stack_top, | ||
| argv, | ||
| &default_env, | ||
| loaded_elf.phdr_vaddr, | ||
| loaded_elf.phnum, | ||
| loaded_elf.phentsize, | ||
|
|
@@ -2576,10 +2584,18 @@ impl ProcessManager { | |
| // We need to write to the new stack pages that we just mapped | ||
| // Since the new page table is not active yet, we need to translate addresses | ||
| // and write via the physical frames | ||
| let default_env: [&[u8]; 5] = [ | ||
| b"PATH=/bin:/sbin\0", | ||
| b"HOME=/\0", | ||
| b"TERM=vt100\0", | ||
| b"USER=root\0", | ||
| b"SHELL=/bin/bsh\0", | ||
| ]; | ||
| let initial_rsp = self.setup_argv_on_stack( | ||
| &new_page_table, | ||
| USER_STACK_TOP, | ||
| argv, | ||
| &default_env, | ||
| loaded_elf.phdr_vaddr, | ||
| loaded_elf.phnum, | ||
| loaded_elf.phentsize, | ||
|
|
@@ -2812,10 +2828,18 @@ impl ProcessManager { | |
| )?; | ||
| } | ||
|
|
||
| let default_env: [&[u8]; 5] = [ | ||
| b"PATH=/bin:/sbin\0", | ||
| b"HOME=/\0", | ||
| b"TERM=vt100\0", | ||
| b"USER=root\0", | ||
| b"SHELL=/bin/bsh\0", | ||
| ]; | ||
| let initial_rsp = self.setup_argv_on_stack( | ||
| &new_page_table, | ||
| user_stack_top, | ||
| argv, | ||
| &default_env, | ||
| loaded_elf.phdr_vaddr, | ||
| loaded_elf.phnum, | ||
| loaded_elf.phentsize, | ||
|
|
@@ -3251,6 +3275,7 @@ impl ProcessManager { | |
| /// | ||
| /// 16 random bytes (for AT_RANDOM) | ||
| /// argv string data (null-terminated strings) | ||
| /// envp string data (null-terminated strings) | ||
| /// --- 8-byte alignment padding --- | ||
| /// AT_NULL (0, 0) // auxv terminator | ||
| /// AT_RANDOM (25, ptr_to_random) // pointer to 16 random bytes | ||
|
|
@@ -3260,6 +3285,9 @@ impl ProcessManager { | |
| /// AT_PHDR (3, phdr_vaddr) // address of program headers in memory | ||
| /// AT_ENTRY (9, entry_point) // program entry point | ||
| /// NULL (envp terminator) // 8 bytes of 0 | ||
| /// envp[m-1] pointer | ||
| /// ... | ||
| /// envp[0] pointer | ||
| /// NULL (argv terminator) // 8 bytes of 0 | ||
| /// argv[n-1] pointer | ||
| /// ... | ||
|
|
@@ -3282,6 +3310,7 @@ impl ProcessManager { | |
| page_table: &crate::memory::process_memory::ProcessPageTable, | ||
| stack_top: u64, | ||
| argv: &[&[u8]], | ||
| envp: &[&[u8]], | ||
| phdr_vaddr: u64, | ||
| phnum: u16, | ||
| phentsize: u16, | ||
|
|
@@ -3325,7 +3354,7 @@ impl ProcessManager { | |
| self.write_byte_to_stack(page_table, random_addr + i as u64, *byte)?; | ||
| } | ||
|
|
||
| // Calculate total space needed for argv strings | ||
| // Calculate total space needed for argv and envp strings | ||
| let mut total_string_space: usize = 0; | ||
| for arg in argv.iter() { | ||
| let len = arg.len(); | ||
|
|
@@ -3335,6 +3364,14 @@ impl ProcessManager { | |
| total_string_space += len + 1; | ||
| } | ||
| } | ||
| for env in envp.iter() { | ||
| let len = env.len(); | ||
| if len > 0 && env[len - 1] == 0 { | ||
| total_string_space += len; | ||
| } else { | ||
| total_string_space += len + 1; | ||
| } | ||
| } | ||
|
|
||
| // Reserve space for strings below the random bytes | ||
| cursor -= total_string_space as u64; | ||
|
|
@@ -3363,15 +3400,34 @@ impl ProcessManager { | |
| } | ||
| } | ||
|
|
||
| // Write envp strings and collect their addresses | ||
| let mut envp_addrs: Vec<u64> = Vec::with_capacity(envp.len()); | ||
|
|
||
| for env in envp.iter() { | ||
| envp_addrs.push(current_string_addr); | ||
|
|
||
| for byte in env.iter() { | ||
| self.write_byte_to_stack(page_table, current_string_addr, *byte)?; | ||
| current_string_addr += 1; | ||
| } | ||
|
|
||
| // Add null terminator if not present | ||
| let len = env.len(); | ||
| if len == 0 || env[len - 1] != 0 { | ||
| self.write_byte_to_stack(page_table, current_string_addr, 0)?; | ||
| current_string_addr += 1; | ||
| } | ||
| } | ||
|
|
||
| // --- Phase 2: Build the pointer/value section below the strings --- | ||
|
|
||
| // Auxiliary vector entries (each is two u64 values: type, value) | ||
| // AT_ENTRY, AT_PHDR, AT_PHNUM, AT_PHENT, AT_PAGESZ, AT_RANDOM, AT_NULL = 7 entries = 14 u64s | ||
| let auxv_count = 7; | ||
| let auxv_space = auxv_count * 2 * 8; // 7 entries * 2 u64s * 8 bytes | ||
|
|
||
| // envp: just a NULL terminator (empty environment) = 1 u64 | ||
| let envp_space = 8; | ||
| // envp: envp.len() pointers + NULL terminator | ||
| let envp_space = (envp.len() + 1) * 8; | ||
|
|
||
| // argv: argc pointers + NULL terminator = (argc + 1) u64s | ||
| let argv_space = (argc + 1) * 8; | ||
|
|
@@ -3405,11 +3461,17 @@ impl ProcessManager { | |
| self.write_u64_to_stack(page_table, write_pos, 0)?; | ||
| write_pos += 8; | ||
|
|
||
| // 4. Write envp NULL terminator (empty environment) | ||
| // 4. Write envp pointers | ||
| for addr in envp_addrs.iter() { | ||
| self.write_u64_to_stack(page_table, write_pos, *addr)?; | ||
| write_pos += 8; | ||
| } | ||
|
|
||
| // 5. Write envp NULL terminator | ||
| self.write_u64_to_stack(page_table, write_pos, 0)?; | ||
| write_pos += 8; | ||
|
|
||
| // 5. Write auxiliary vector entries | ||
| // 6. Write auxiliary vector entries | ||
| // AT_ENTRY (9) - program entry point | ||
| self.write_u64_to_stack(page_table, write_pos, 9)?; // AT_ENTRY | ||
| write_pos += 8; | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Epoll instance leaked when dup2 overwrites epoll fd
Low Severity
When
dup2(ordup3) overwrites anew_fdthat is an epoll fd, the old entry is taken from the table and its kind is matched for cleanup.FdKind::Epollfalls through to_ => {}without callingremove_instance, leaking the epoll instance in the globalEPOLL_INSTANCESregistry.