Skip to content

Commit

Permalink
Parse kernel arguments using clap
Browse files Browse the repository at this point in the history
  • Loading branch information
mkroening committed Jan 3, 2022
1 parent 1affe92 commit 7da74cf
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 44 deletions.
5 changes: 3 additions & 2 deletions src/bin/uhyve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ struct Args {

/// Arguments to forward to the kernel
#[structopt(parse(from_os_str))]
_arguments: Vec<OsString>,
args: Vec<OsString>,
}

#[derive(Parser, Debug)]
Expand Down Expand Up @@ -285,7 +285,7 @@ impl From<Args> for Params {
_mac,
},
kernel: _,
_arguments,
args,
} = args;
Self {
verbose,
Expand All @@ -305,6 +305,7 @@ impl From<Args> for Params {
nic,
#[cfg(target_os = "linux")]
gdb_port,
args,
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/linux/uhyve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use kvm_ioctls::VmFd;
use log::debug;
use nix::sys::mman::*;
use std::cmp;
use std::ffi::OsString;
use std::fmt;
use std::hint;
use std::mem;
Expand Down Expand Up @@ -133,6 +134,7 @@ pub struct Uhyve {
mem: MmapMemory,
num_cpus: u32,
path: PathBuf,
args: Vec<OsString>,
boot_info: *const BootInfo,
verbose: bool,
ip: Option<Ipv4Addr>,
Expand Down Expand Up @@ -271,6 +273,7 @@ impl Uhyve {
mem,
num_cpus: cpu_count,
path: kernel_path,
args: params.args,
boot_info: ptr::null(),
verbose: params.verbose,
ip: params.ip,
Expand Down Expand Up @@ -339,6 +342,7 @@ impl Vm for Uhyve {
Ok(UhyveCPU::new(
id,
self.path.clone(),
self.args.clone(),
self.vm.create_vcpu(id.try_into().unwrap())?,
vm_start,
tx,
Expand Down
8 changes: 8 additions & 0 deletions src/linux/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::vm::VcpuStopReason;
use crate::vm::VirtualCPU;
use kvm_bindings::*;
use kvm_ioctls::{VcpuExit, VcpuFd};
use std::ffi::OsString;
use std::path::Path;
use std::path::PathBuf;
use std::slice;
Expand All @@ -27,6 +28,7 @@ pub struct UhyveCPU {
vcpu: VcpuFd,
vm_start: usize,
kernel_path: PathBuf,
args: Vec<OsString>,
tx: Option<std::sync::mpsc::SyncSender<usize>>,
virtio_device: Arc<Mutex<VirtioNetPciDevice>>,
pci_addr: Option<u32>,
Expand All @@ -42,6 +44,7 @@ impl UhyveCPU {
pub fn new(
id: u32,
kernel_path: PathBuf,
args: Vec<OsString>,
vcpu: VcpuFd,
vm_start: usize,
tx: Option<std::sync::mpsc::SyncSender<usize>>,
Expand All @@ -52,6 +55,7 @@ impl UhyveCPU {
vcpu,
vm_start,
kernel_path,
args,
tx,
virtio_device,
pci_addr: None,
Expand Down Expand Up @@ -256,6 +260,10 @@ impl VirtualCPU for UhyveCPU {
self.kernel_path.as_path()
}

fn args(&self) -> &[OsString] {
self.args.as_slice()
}

fn host_address(&self, addr: usize) -> usize {
addr + self.vm_start
}
Expand Down
4 changes: 4 additions & 0 deletions src/macos/aarch64/uhyve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::vm::Vm;
use libc;
use libc::c_void;
use log::debug;
use std::ffi::OsString;
use std::net::Ipv4Addr;
use std::path::Path;
use std::path::PathBuf;
Expand All @@ -21,6 +22,7 @@ pub struct Uhyve {
guest_mem: *mut c_void,
num_cpus: u32,
path: PathBuf,
args: Vec<OsString>,
boot_info: *const BootInfo,
verbose: bool,
}
Expand Down Expand Up @@ -88,6 +90,7 @@ impl Uhyve {
guest_mem: mem,
num_cpus: params.cpu_count.get(),
path: kernel_path,
args: params.args,
boot_info: ptr::null(),
verbose: params.verbose,
};
Expand Down Expand Up @@ -135,6 +138,7 @@ impl Vm for Uhyve {
Ok(UhyveCPU::new(
id,
self.path.clone(),
self.args.clone(),
self.guest_mem as usize,
))
}
Expand Down
9 changes: 8 additions & 1 deletion src/macos/aarch64/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::vm::HypervisorResult;
use crate::vm::VcpuStopReason;
use crate::vm::VirtualCPU;
use log::debug;
use std::ffi::OsString;
use std::path::Path;
use std::path::PathBuf;
use xhypervisor;
Expand All @@ -14,15 +15,17 @@ use xhypervisor::{Register, SystemRegister, VirtualCpuExitReason};
pub struct UhyveCPU {
id: u32,
kernel_path: PathBuf,
args: Vec<OsString>,
vcpu: xhypervisor::VirtualCpu,
vm_start: usize,
}

impl UhyveCPU {
pub fn new(id: u32, kernel_path: PathBuf, vm_start: usize) -> UhyveCPU {
pub fn new(id: u32, kernel_path: PathBuf, args: Vec<OsString>, vm_start: usize) -> UhyveCPU {
Self {
id,
kernel_path,
args,
vcpu: xhypervisor::VirtualCpu::new().unwrap(),
vm_start,
}
Expand Down Expand Up @@ -50,6 +53,10 @@ impl VirtualCPU for UhyveCPU {
self.kernel_path.as_path()
}

fn args(&self) -> &[OsString] {
self.args.as_slice()
}

fn host_address(&self, addr: usize) -> usize {
addr + self.vm_start
}
Expand Down
4 changes: 4 additions & 0 deletions src/macos/x86_64/uhyve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::x86_64::create_gdt_entry;
use libc;
use libc::c_void;
use log::debug;
use std::ffi::OsString;
use std::mem;
use std::net::Ipv4Addr;
use std::path::Path;
Expand All @@ -27,6 +28,7 @@ pub struct Uhyve {
guest_mem: *mut c_void,
num_cpus: u32,
path: PathBuf,
args: Vec<OsString>,
boot_info: *const BootInfo,
ioapic: Arc<Mutex<IoApic>>,
verbose: bool,
Expand Down Expand Up @@ -85,6 +87,7 @@ impl Uhyve {
guest_mem: mem,
num_cpus: params.cpu_count.get(),
path: kernel_path,
args: params.args,
boot_info: ptr::null(),
ioapic: Arc::new(Mutex::new(IoApic::new())),
verbose: params.verbose,
Expand Down Expand Up @@ -133,6 +136,7 @@ impl Vm for Uhyve {
Ok(UhyveCPU::new(
id,
self.path.clone(),
self.args.clone(),
self.guest_mem as usize,
self.ioapic.clone(),
))
Expand Down
8 changes: 8 additions & 0 deletions src/macos/x86_64/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use burst::x86::{disassemble_64, InstructionOperation, OperandType};
use lazy_static::lazy_static;
use log::{debug, trace};
use std::arch::x86_64::__cpuid_count;
use std::ffi::OsString;
use std::path::Path;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
Expand Down Expand Up @@ -146,6 +147,7 @@ lazy_static! {
pub struct UhyveCPU {
id: u32,
kernel_path: PathBuf,
args: Vec<OsString>,
vcpu: xhypervisor::VirtualCpu,
vm_start: usize,
apic_base: u64,
Expand All @@ -156,12 +158,14 @@ impl UhyveCPU {
pub fn new(
id: u32,
kernel_path: PathBuf,
args: Vec<OsString>,
vm_start: usize,
ioapic: Arc<Mutex<IoApic>>,
) -> UhyveCPU {
UhyveCPU {
id,
kernel_path,
args,
vcpu: xhypervisor::VirtualCpu::new().unwrap(),
vm_start,
apic_base: APIC_DEFAULT_BASE,
Expand Down Expand Up @@ -626,6 +630,10 @@ impl VirtualCPU for UhyveCPU {
self.kernel_path.as_path()
}

fn args(&self) -> &[OsString] {
self.args.as_slice()
}

fn host_address(&self, addr: usize) -> usize {
addr + self.vm_start
}
Expand Down
5 changes: 5 additions & 0 deletions src/params.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#[cfg(target_os = "linux")]
use std::net::Ipv4Addr;
use std::{
ffi::OsString,
fmt,
num::{NonZeroU32, ParseIntError, TryFromIntError},
str::FromStr,
Expand Down Expand Up @@ -47,6 +48,9 @@ pub struct Params {
/// Name of the network interface
#[cfg(target_os = "linux")]
pub nic: Option<String>,

/// Arguments to forward to the kernel
pub args: Vec<OsString>,
}

#[allow(clippy::derivable_impls)]
Expand All @@ -70,6 +74,7 @@ impl Default for Params {
mask: Default::default(),
#[cfg(target_os = "linux")]
nic: Default::default(),
args: Default::default(),
}
}
}
Expand Down
63 changes: 22 additions & 41 deletions src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use goblin::elf64::header::ET_DYN;
use goblin::elf64::program_header::{PT_LOAD, PT_TLS};
use goblin::elf64::reloc::*;
use log::{debug, error, warn};
use std::ffi::OsString;
use std::io::Write;
use std::net::Ipv4Addr;
use std::os::unix::ffi::OsStrExt;
Expand Down Expand Up @@ -140,36 +141,25 @@ pub trait VirtualCPU {
/// Returns the (host) path of the kernel binary.
fn kernel_path(&self) -> &Path;

fn args(&self) -> &[OsString];

fn cmdsize(&self, syssize: &mut SysCmdsize) {
syssize.argc = 0;
syssize.envc = 0;

let mut counter: i32 = 0;
let mut separator_pos: i32 = 0;
let path = self.kernel_path();
let mut found_separator = false;
syssize.argsz[0] = path.as_os_str().len() as i32 + 1;

for argument in std::env::args_os() {
if !found_separator && argument == "--" {
separator_pos = counter + 1;
found_separator = true;
}

if found_separator && counter >= separator_pos {
syssize.argsz[(counter - separator_pos + 1) as usize] = argument.len() as i32 + 1;
}
let mut counter = 0;
for argument in self.args() {
syssize.argsz[(counter + 1) as usize] = argument.len() as i32 + 1;

counter += 1;
}

if found_separator && counter >= separator_pos {
syssize.argc = counter - separator_pos + 1;
} else {
syssize.argc = 1;
}
syssize.argc = counter + 1;

counter = 0;
let mut counter = 0;
for (key, value) in std::env::vars_os() {
if counter < MAX_ENVC.try_into().unwrap() {
syssize.envsz[counter as usize] = (key.len() + value.len()) as i32 + 2;
Expand All @@ -185,10 +175,7 @@ pub trait VirtualCPU {

/// Copies the arguments end environment of the application into the VM's memory.
fn cmdval(&self, syscmdval: &SysCmdval) {
let mut counter: i32 = 0;
let argv = self.host_address(syscmdval.argv as usize);
let mut found_separator = false;
let mut separator_pos: i32 = 0;

// copy kernel path as first argument
{
Expand All @@ -204,32 +191,26 @@ pub trait VirtualCPU {
}

// Copy the application arguments into the vm memory
for argument in std::env::args_os() {
if !found_separator && argument == "--" {
separator_pos = counter + 1;
found_separator = true;
}

if found_separator && counter >= separator_pos {
let argvptr = unsafe {
self.host_address(
*((argv + (counter - separator_pos + 1) as usize * mem::size_of::<usize>())
as *mut *mut u8) as usize,
)
};
let len = argument.len();
let slice = unsafe { slice::from_raw_parts_mut(argvptr as *mut u8, len + 1) };
let mut counter = 0;
for argument in self.args() {
let argvptr = unsafe {
self.host_address(
*((argv + (counter + 1) as usize * mem::size_of::<usize>()) as *mut *mut u8)
as usize,
)
};
let len = argument.len();
let slice = unsafe { slice::from_raw_parts_mut(argvptr as *mut u8, len + 1) };

// Create string for environment variable
slice[0..len].copy_from_slice(argument.as_bytes());
slice[len] = 0;
}
// Create string for environment variable
slice[0..len].copy_from_slice(argument.as_bytes());
slice[len] = 0;

counter += 1;
}

// Copy the environment variables into the vm memory
counter = 0;
let mut counter = 0;
let envp = self.host_address(syscmdval.envp as usize);
for (key, value) in std::env::vars_os() {
if counter < MAX_ENVC.try_into().unwrap() {
Expand Down

0 comments on commit 7da74cf

Please sign in to comment.