Skip to content
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

Support dynamic relocation in libuser #247

Merged
merged 4 commits into from
Apr 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 30 additions & 34 deletions Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ script = ["cp linker-scripts/bootstrap.ld link.T"]
workspace = false
script = ["cp linker-scripts/kernel.ld link.T"]

[tasks.userspace-linker]
workspace = false
script = ["cp linker-scripts/userspace.ld link.T"]

[tasks.install-rust-src]
install_crate = { rustup_component_name = "rust-src" }

Expand Down Expand Up @@ -55,72 +51,72 @@ args = ["xbuild", "--target=i386-unknown-none", "--package=sunrise-kernel", "--r
[tasks.vi]
workspace = false
description = "Compiles sunrise-vi"
dependencies = ["userspace-linker", "install-rust-src"]
dependencies = ["install-rust-src"]
command = "cargo"
args = ["xbuild", "--target=i386-unknown-none", "--package=sunrise-vi"]
args = ["xbuild", "--target=i386-unknown-none-user", "--package=sunrise-vi"]

[tasks.vi-release]
workspace = false
description = "Compiles sunrise-vi"
dependencies = ["userspace-linker", "install-rust-src"]
dependencies = ["install-rust-src"]
command = "cargo"
args = ["xbuild", "--target=i386-unknown-none", "--package=sunrise-vi", "--release"]
args = ["xbuild", "--target=i386-unknown-none-user", "--package=sunrise-vi", "--release"]

[tasks.sm]
workspace = false
description = "Compiles sunrise-sm"
dependencies = ["userspace-linker", "install-rust-src"]
dependencies = ["install-rust-src"]
command = "cargo"
args = ["xbuild", "--target=i386-unknown-none", "--package=sunrise-sm"]
args = ["xbuild", "--target=i386-unknown-none-user", "--package=sunrise-sm"]

[tasks.sm-release]
workspace = false
description = "Compiles sunrise-sm"
dependencies = ["userspace-linker", "install-rust-src"]
dependencies = ["install-rust-src"]
command = "cargo"
args = ["xbuild", "--target=i386-unknown-none", "--package=sunrise-sm", "--release"]
args = ["xbuild", "--target=i386-unknown-none-user", "--package=sunrise-sm", "--release"]

[tasks.shell]
workspace = false
description = "Compiles sunrise-shell"
dependencies = ["userspace-linker", "install-rust-src"]
dependencies = ["install-rust-src"]
command = "cargo"
args = ["xbuild", "--target=i386-unknown-none", "--package=sunrise-shell"]
args = ["xbuild", "--target=i386-unknown-none-user", "--package=sunrise-shell"]

[tasks.shell-release]
workspace = false
description = "Compiles sunrise-shell"
dependencies = ["userspace-linker", "install-rust-src"]
dependencies = ["install-rust-src"]
command = "cargo"
args = ["xbuild", "--target=i386-unknown-none", "--package=sunrise-shell", "--release"]
args = ["xbuild", "--target=i386-unknown-none-user", "--package=sunrise-shell", "--release"]

[tasks.clock]
workspace = false
description = "Compiles sunrise-clock"
dependencies = ["userspace-linker", "install-rust-src"]
dependencies = ["install-rust-src"]
command = "cargo"
args = ["xbuild", "--target=i386-unknown-none", "--package=sunrise-clock"]
args = ["xbuild", "--target=i386-unknown-none-user", "--package=sunrise-clock"]

[tasks.clock-release]
workspace = false
description = "Compiles sunrise-clock"
dependencies = ["userspace-linker", "install-rust-src"]
dependencies = ["install-rust-src"]
command = "cargo"
args = ["xbuild", "--target=i386-unknown-none", "--package=sunrise-clock", "--release"]
args = ["xbuild", "--target=i386-unknown-none-user", "--package=sunrise-clock", "--release"]

[tasks.ahci]
workspace = false
description = "Compiles sunrise-ahci"
dependencies = ["userspace-linker", "install-rust-src"]
dependencies = ["install-rust-src"]
command = "cargo"
args = ["xbuild", "--target=i386-unknown-none", "--package=sunrise-ahci"]
args = ["xbuild", "--target=i386-unknown-none-user", "--package=sunrise-ahci"]

[tasks.ahci-release]
workspace = false
description = "Compiles sunrise-ahci"
dependencies = ["userspace-linker", "install-rust-src"]
dependencies = ["install-rust-src"]
command = "cargo"
args = ["xbuild", "--target=i386-unknown-none", "--package=sunrise-ahci", "--release"]
args = ["xbuild", "--target=i386-unknown-none-user", "--package=sunrise-ahci", "--release"]

[tasks.userspace]
workspace = false
Expand All @@ -140,11 +136,11 @@ script = [
'''
cp target/i386-unknown-none/debug/sunrise-bootstrap isofiles/boot/
cp target/i386-unknown-none/debug/sunrise-kernel isofiles/boot/
cp target/i386-unknown-none/debug/sunrise-shell isofiles/boot/
cp target/i386-unknown-none/debug/sunrise-clock isofiles/boot/
cp target/i386-unknown-none/debug/sunrise-sm isofiles/boot/
cp target/i386-unknown-none/debug/sunrise-vi isofiles/boot/
cp target/i386-unknown-none/debug/sunrise-ahci isofiles/boot/
cp target/i386-unknown-none-user/debug/sunrise-shell isofiles/boot/
cp target/i386-unknown-none-user/debug/sunrise-clock isofiles/boot/
cp target/i386-unknown-none-user/debug/sunrise-sm isofiles/boot/
cp target/i386-unknown-none-user/debug/sunrise-vi isofiles/boot/
cp target/i386-unknown-none-user/debug/sunrise-ahci isofiles/boot/
mkisofs-rs external/grub/isofiles isofiles -o os.iso -b boot/grub/i386-pc/eltorito.img --no-emul-boot --boot-info-table --embedded-boot external/grub/embedded.img
'''
]
Expand All @@ -157,11 +153,11 @@ script = [
'''
cp target/i386-unknown-none/release/sunrise-bootstrap isofiles/boot/
cp target/i386-unknown-none/release/sunrise-kernel isofiles/boot/
cp target/i386-unknown-none/release/sunrise-shell isofiles/boot/
cp target/i386-unknown-none/release/sunrise-clock isofiles/boot/
cp target/i386-unknown-none/release/sunrise-sm isofiles/boot/
cp target/i386-unknown-none/release/sunrise-vi isofiles/boot/
cp target/i386-unknown-none/release/sunrise-ahci isofiles/boot/
cp target/i386-unknown-none-user/release/sunrise-shell isofiles/boot/
cp target/i386-unknown-none-user/release/sunrise-clock isofiles/boot/
cp target/i386-unknown-none-user/release/sunrise-sm isofiles/boot/
cp target/i386-unknown-none-user/release/sunrise-vi isofiles/boot/
cp target/i386-unknown-none-user/release/sunrise-ahci isofiles/boot/
mkisofs-rs external/grub/isofiles isofiles -o os.iso -b boot/grub/i386-pc/eltorito.img --no-emul-boot --boot-info-table --embedded-boot external/grub/embedded.img
'''
]
Expand Down
26 changes: 26 additions & 0 deletions i386-unknown-none-user.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"llvm-target": "i386-unknown-none",
marysaka marked this conversation as resolved.
Show resolved Hide resolved
"data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128",
"arch": "x86",
"target-endian": "little",
"target-pointer-width": "32",
"target-c-int-width": "32",
"os": "none",
"linker": "rust-lld",
"linker-flavor": "ld.lld",
"linker-is-gnu": true,
"pre-link-args": {
"ld.lld": [
"-Tlinker-scripts/userspace.ld"
]
},
"executables": true,
"env": "user",
"position-independent-executables": true,
"dynamic-linking": false,
"has-elf-tls": false,
"has-rpath": false,
"features": "-mmx,-sse,+soft-float",
"disable-redzone": true,
"panic-strategy": "abort"
}
10 changes: 7 additions & 3 deletions kernel/src/elf_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ pub fn load_builtin(process_memory: &mut ProcessMemory, module: &MappedGrubModul
}

// return the entry point
let entry_point = elf.header.pt2.entry_point();
// TODO: ASLR
// BODY: We should generate a random aslr base.
let entry_point = 0x400000 + elf.header.pt2.entry_point();
info!("Entry point : {:#x?}", entry_point);

entry_point as usize
Expand All @@ -133,8 +135,10 @@ fn load_segment(process_memory: &mut ProcessMemory, segment: ProgramHeader<'_>,
flags |= MappingAccessRights::EXECUTABLE
}

let virtual_addr = 0x400000 + segment.virtual_addr() as usize;
Orycterope marked this conversation as resolved.
Show resolved Hide resolved

// Create the mapping in UserLand
let userspace_addr = VirtualAddress(segment.virtual_addr() as usize);
let userspace_addr = VirtualAddress(virtual_addr);
process_memory.create_regular_mapping(userspace_addr, mem_size_total, flags)
.expect("Cannot load segment");

Expand Down Expand Up @@ -164,7 +168,7 @@ fn load_segment(process_memory: &mut ProcessMemory, segment: ProgramHeader<'_>,
}

info!("Loaded segment - VirtAddr {:#010x}, FileSize {:#010x}, MemSize {:#010x} {}{}{}",
segment.virtual_addr(), segment.file_size(), segment.mem_size(),
virtual_addr, segment.file_size(), segment.mem_size(),
match segment.flags().is_read() { true => 'R', false => ' '},
match segment.flags().is_write() { true => 'W', false => ' '},
match segment.flags().is_execute() { true => 'X', false => ' '},
Expand Down
63 changes: 63 additions & 0 deletions libuser/src/crt0/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//! libuser CRT0
//! This module is a minimal RT0 handling the entry point of the application.
//! It handles relocation, clean the bss and then finally call start_main.

use core::ptr;

mod relocation;

/// Executable entrypoint. Handle relocations and calls real_start.
#[cfg(target_os = "none")]
#[naked]
#[no_mangle]
#[link_section = ".text.crt0"]
pub unsafe extern fn start() {
asm!("
.intel_syntax noprefix
get_aslr_base:
call _start_shim
eip_pos:
.int module_header - get_aslr_base
// As x86 has variable instruction length, this is going to be the offset to the aslr base
.int eip_pos - get_aslr_base
_start_shim:
pop eax

// Save eip_pos address
mov ecx, eax

// Compute ASLR base because hey we don't have a choice
sub eax, [eax + 0x4]
mov ebx, eax

// Compute mod0 offset
add ebx, [ecx]

// Relocate the module
push ebx
push eax
call relocate_self

// Clean .bss
push ebx
call clean_bss

call real_start
");
}

/// Clean module bss.
/// NOTE: Even if the bss should be cleared before calling anything in Rust, all functions used here are guaranteed to not use the bss.
#[cfg(target_os = "none")]
#[no_mangle]
#[link_section = ".text.crt0"]
pub unsafe extern fn clean_bss(module_header: *const relocation::ModuleHeader) {
let module_header_address = module_header as *mut u8;
let module_header = &(*module_header);

let bss_start_address = module_header_address.add(module_header.bss_start_off as usize) as *mut u8;
let bss_end_address = module_header_address.add(module_header.bss_end_off as usize) as *mut u8;

let count = bss_end_address as usize - bss_start_address as usize;
ptr::write_bytes(bss_start_address, 0, count);
}
Loading