Skip to content

Commit afaed72

Browse files
committed
Refactoring
1 parent 23d774a commit afaed72

3 files changed

Lines changed: 42 additions & 53 deletions

File tree

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "uruntime"
3-
version = "0.0.2"
3+
version = "0.0.3"
44
readme = "README.md"
55
license = "MIT"
66
repository = "https://github.com/VHSgunzo/uruntime"
@@ -31,7 +31,7 @@ pie-ulexec = ["dep:userland-execve"]
3131
indexmap = "2.6.0"
3232

3333
[dependencies]
34-
which = "6.0.3"
34+
which = "7.0.0"
3535
cfg-if = "1.0.0"
3636
goblin = "0.9.0"
3737
num_cpus = "1.16.0"

build.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
use std::path::Path;
2-
use std::process::exit;
3-
use std::{env, process::Command};
4-
use std::os::unix::fs::{symlink, PermissionsExt};
5-
use std::fs::{create_dir, metadata, remove_file, set_permissions};
1+
use std::{
2+
env,
3+
path::Path,
4+
process::{exit, Command},
5+
os::unix::fs::{symlink, PermissionsExt},
6+
fs::{create_dir, remove_file, set_permissions, Permissions}
7+
};
68

79
use indexmap::IndexMap;
810

11+
912
fn main() {
1013
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
1114

@@ -46,10 +49,7 @@ fn main() {
4649
exit(1)
4750
}
4851

49-
let mut permissions = metadata(&asset_path)
50-
.expect(&format!("Unable to read metadata: {asset}")).permissions();
51-
permissions.set_mode(0o755);
52-
set_permissions(&asset_path, permissions)
52+
set_permissions(&asset_path, Permissions::from_mode(0o755))
5353
.expect(&format!("Unable to set permissions: {asset}"));
5454
}
5555

src/main.rs

Lines changed: 31 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
use std::{
2-
time::Instant,
32
path::PathBuf,
4-
process::{exit, Command},
53
thread::{sleep, spawn},
4+
process::{exit, Command},
5+
time::{Instant, Duration},
66
io::{Read, Seek, SeekFrom},
77
os::unix::fs::{symlink, MetadataExt},
8-
{env::{self, current_exe}, fs, io, time},
8+
{env::{self, current_exe}, fs, time},
9+
io::{ErrorKind::NotFound, Error, Result},
910
fs::{create_dir, create_dir_all, read_to_string, remove_dir, remove_file, File},
1011
};
11-
use io::{ErrorKind::NotFound, Error, Result};
1212

1313
use which::which;
1414
use cfg_if::cfg_if;
1515
use goblin::elf::Elf;
1616
use memfd_exec::{MemFdExecutable, Stdio};
1717
use nix::sys::{wait::waitpid, signal::{Signal, kill}};
1818
use nix::unistd::{access, fork, getcwd, AccessFlags, ForkResult, Pid};
19-
use signal_hook::{consts::{SIGINT, SIGTERM, SIGQUIT}, iterator::Signals};
19+
use signal_hook::{consts::{SIGINT, SIGTERM, SIGQUIT, SIGHUP}, iterator::Signals};
2020

2121
#[cfg(feature = "pie-ulexec")]
2222
mod pie_ulexec {
@@ -59,6 +59,7 @@ struct Image {
5959
is_dwar: bool,
6060
}
6161

62+
6263
fn get_image(path: &PathBuf, offset: u64) -> Result<Image> {
6364
let mut file = File::open(path)?;
6465
let mut buffer = [0; 4];
@@ -167,38 +168,26 @@ fn is_pie(bytes: &Vec<u8>) -> bool {
167168
}
168169

169170
fn get_runtime_size(path: &PathBuf) -> Result<u64> {
170-
const MAX_SIZE: usize = 20971520; // 20 MB
171-
const BUFFER_SIZE: usize = 1048576; // 1 MB
172-
let mut runtime = File::open(path)?;
173-
let mut buffer = Vec::with_capacity(MAX_SIZE);
174-
let mut total_read = 0;
175-
loop {
176-
if total_read >= MAX_SIZE {
177-
return Err(Error::new(std::io::ErrorKind::InvalidInput,
178-
format!("Reached ELF runtime MAX_SIZE buffer limit of {} MB", MAX_SIZE / 1024 / 1024)
179-
));
180-
}
181-
let mut chunk = [0; BUFFER_SIZE];
182-
let bytes_read = runtime.read(&mut chunk)?;
183-
if bytes_read == 0 {
184-
return Err(Error::new(std::io::ErrorKind::UnexpectedEof,
185-
format!("Reached end of file: {:?}", path)
186-
));
187-
}
188-
buffer.extend_from_slice(&chunk[..bytes_read]);
189-
total_read += bytes_read;
190-
if let Ok(elf) = Elf::parse(&buffer) {
191-
let ehdr = elf.header;
192-
let sht_end = ehdr.e_shoff + (ehdr.e_shentsize as u64 * ehdr.e_shnum as u64);
193-
let last_shdr = elf.section_headers.last().unwrap();
194-
let last_section_end = last_shdr.sh_offset + last_shdr.sh_size;
195-
return if sht_end > last_section_end {
196-
Ok(sht_end)
197-
} else {
198-
Ok(last_section_end)
199-
}
200-
} else { continue }
201-
}
171+
let mut file = File::open(path)?;
172+
let mut elf_header_raw = [0; 64];
173+
file.read_exact(&mut elf_header_raw)?;
174+
let section_table_offset = u64::from_le_bytes(elf_header_raw[40..48].try_into().unwrap()); // e_shoff
175+
let section_count = u16::from_le_bytes(elf_header_raw[60..62].try_into().unwrap()); // e_shnum
176+
let section_table_size = section_count as u64 * 64;
177+
let required_bytes = section_table_offset + section_table_size;
178+
let mut header_data = vec![0; required_bytes as usize];
179+
file.seek(SeekFrom::Start(0))?;
180+
file.read_exact(&mut header_data)?;
181+
let elf = Elf::parse(&header_data)
182+
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
183+
let section_table_end =
184+
elf.header.e_shoff + (elf.header.e_shentsize as u64 * elf.header.e_shnum as u64);
185+
let last_section_end = elf
186+
.section_headers
187+
.last()
188+
.map(|section| section.sh_offset + section.sh_size)
189+
.unwrap_or(0);
190+
Ok(section_table_end.max(last_section_end))
202191
}
203192

204193
fn random_string(length: usize) -> String {
@@ -269,7 +258,7 @@ fn embed_exec(exec_name: &str, exec_bytes: Vec<u8>, exec_args: Vec<String>) {
269258
CString::new(format!("{}={}", key, value)).unwrap()
270259
).collect();
271260
spawn(move || {
272-
sleep(time::Duration::from_millis(1));
261+
sleep(Duration::from_millis(1));
273262
close(memfd_raw).unwrap()
274263
});
275264
userland_execve::exec(
@@ -302,14 +291,14 @@ fn is_mount_point(path: &PathBuf) -> Result<bool> {
302291
}
303292
}
304293

305-
fn wait_mount(path: &PathBuf, timeout: time::Duration) -> bool {
294+
fn wait_mount(path: &PathBuf, timeout: Duration) -> bool {
306295
let start_time = Instant::now();
307296
while !path.exists() || !is_mount_point(path).unwrap_or(false) {
308297
if start_time.elapsed() >= timeout {
309298
eprintln!("Timeout reached while waiting for mount: {:?}", path);
310299
return false
311300
}
312-
sleep(time::Duration::from_millis(1))
301+
sleep(Duration::from_millis(1))
313302
}
314303
true
315304
}
@@ -452,7 +441,7 @@ fn main() {
452441

453442
match unsafe { fork() } {
454443
Ok(ForkResult::Parent { child: child_pid }) => {
455-
if !wait_mount(&mount_dir, time::Duration::from_millis(500)) {
444+
if !wait_mount(&mount_dir, Duration::from_millis(1000)) {
456445
remove_mnt(mount_dirs);
457446
exit(1)
458447
}
@@ -494,7 +483,7 @@ fn main() {
494483
spawn(move || {
495484
for signal in signals.forever() {
496485
match signal {
497-
SIGINT | SIGTERM | SIGQUIT => {
486+
SIGINT | SIGTERM | SIGQUIT | SIGHUP => {
498487
let _ = kill(pid, Signal::SIGTERM);
499488
break
500489
}

0 commit comments

Comments
 (0)