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

add windows crash_dump support & sys split #713

Merged
merged 2 commits into from
Nov 28, 2024
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
3 changes: 3 additions & 0 deletions plugins/lib/rust/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.vscode/
dev.sh
target/
21 changes: 18 additions & 3 deletions plugins/lib/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "plugins"
version = "0.1.0"
authors = ["zhanglei.sec <[email protected]>"]
edition = "2018"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
Expand All @@ -23,9 +23,24 @@ serde_json = "1"
protobuf-codegen-pure = "2.3"

[dependencies.windows]
version = "0.48.0"
version = "0.58.0"
features = [
"Win32_System_Diagnostics_ToolHelp",
"Win32_Foundation",
"Win32_Security",
"Win32_Storage_FileSystem",
"Win32_System_Console",
"Win32_System_Services",
"Win32_System_Kernel",
"Win32_System_JobObjects",
"Win32_System_Memory",
"Win32_System_Threading",
"Win32_System_Diagnostics",
"Win32_System_Diagnostics_ToolHelp",
"Win32_System_Diagnostics_Debug_Extensions",
]


# Library dependencies (Windows)
[target.'cfg(target_os = "windows")'.dependencies]
anyhow = "1.0"
zip = "2.2"
114 changes: 25 additions & 89 deletions plugins/lib/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
pub mod bridge;
pub mod logger;

pub use bridge::*;
use crossbeam::channel::{select, tick};
use log::{debug, info};
use parking_lot::Mutex;
use protobuf::Message;
use signal_hook::consts::SIGTERM;
use std::{
env,
fs::File,
Expand All @@ -16,15 +7,17 @@ use std::{
time::Duration,
};

#[cfg(target_family = "unix")]
use signal_hook::{consts::SIGUSR1, iterator::Signals};
#[cfg(target_family = "unix")]
use std::os::unix::prelude::FromRawFd;
use crossbeam::channel::{select, tick};
use log::debug;
use parking_lot::Mutex;
use protobuf::Message;

pub mod logger;

#[cfg(target_family = "windows")]
use std::os::windows::prelude::{FromRawHandle, RawHandle};
#[cfg(target_family = "windows")]
use windows::Win32::System::Console::{GetStdHandle, STD_INPUT_HANDLE, STD_OUTPUT_HANDLE};
pub mod bridge;
pub use bridge::*;

pub mod sys;

#[derive(Clone)]
pub enum EncodeType {
Expand All @@ -37,62 +30,26 @@ pub struct Client {
writer: Arc<Mutex<BufWriter<File>>>,
reader: Arc<Mutex<BufReader<File>>>,
}
#[cfg(feature = "debug")]
const READ_PIPE_FD: i32 = 0;
#[cfg(not(feature = "debug"))]
const READ_PIPE_FD: i32 = 3;
#[cfg(feature = "debug")]
const WRITE_PIPE_FD: i32 = 1;
#[cfg(not(feature = "debug"))]
const WRITE_PIPE_FD: i32 = 4;
const HIGH_PRIORIT_FD: i32 = 5;

impl Client {

pub fn can_use_high() -> bool {
match env::var("ELKEID_PLUGIN_HIGH_PRIORITY_PIPE") {
Ok(value) => {
if !value.is_empty() {
return true;
}

}
Err(_) => {
return false;
}

}
false
}
pub fn new(ignore_terminate: bool) -> Self {

let writer = Arc::new(Mutex::new(BufWriter::with_capacity(512 * 1024, unsafe {
#[cfg(target_family = "unix")]
{
File::from_raw_fd(WRITE_PIPE_FD)
}

#[cfg(target_family = "windows")]
{
let raw_handle = GetStdHandle(STD_OUTPUT_HANDLE).unwrap();
File::from_raw_handle(raw_handle.0 as _)
}
})));
let writer = sys::get_writer();
let mut high_writer = writer.clone();
if Self::can_use_high() {
high_writer = Arc::new(Mutex::new(BufWriter::with_capacity(512 * 1024, unsafe {
#[cfg(target_family = "unix")]
{
File::from_raw_fd(HIGH_PRIORIT_FD)
}

#[cfg(target_family = "windows")]
{
let raw_handle = GetStdHandle(STD_OUTPUT_HANDLE).unwrap();
File::from_raw_handle(raw_handle.0 as _)
}
})));

if Self::can_use_high() {
high_writer = sys::get_high_writer();
let high_writer_c = high_writer.clone();
thread::spawn(move || {
let ticker = tick(Duration::from_millis(200));
Expand All @@ -109,19 +66,8 @@ impl Client {
});
}

let reader = Arc::new(Mutex::new(BufReader::new(unsafe {
#[cfg(target_family = "unix")]
{
File::from_raw_fd(READ_PIPE_FD)
}
let reader = sys::get_reader();

#[cfg(target_family = "windows")]
{
let raw_handle = GetStdHandle(STD_INPUT_HANDLE).unwrap();
File::from_raw_handle(raw_handle.0 as _)
}
})));

let writer_c = writer.clone();
thread::spawn(move || {
let ticker = tick(Duration::from_millis(200));
Expand All @@ -136,26 +82,18 @@ impl Client {
}
}
});
#[cfg(target_family = "unix")]

sys::regist_exception_handler();

if ignore_terminate {
let mut signals = Signals::new(&[SIGTERM, SIGUSR1]).unwrap();
thread::spawn(move || {
for sig in signals.forever() {
if sig == SIGTERM {
info!("received signal: {:?}, wait 3 secs to exit", sig);
thread::sleep(Duration::from_secs(3));
unsafe {
if Self::can_use_high() {
libc::close(HIGH_PRIORIT_FD);
}
libc::close(WRITE_PIPE_FD);
libc::close(READ_PIPE_FD);
}
}
}
});
sys::ignore_terminate()
}

Self {
high_writer,
writer,
reader,
}
Self { high_writer, writer, reader }
}
pub fn send_record(&mut self, rec: &Record) -> Result<(), Error> {
let mut w = self.writer.lock();
Expand All @@ -176,7 +114,6 @@ impl Client {
}
}
pub fn send_record_high_priority(&mut self, rec: &Record) -> Result<(), Error> {

let mut w = self.high_writer.lock();
#[cfg(not(feature = "debug"))]
{
Expand Down Expand Up @@ -209,7 +146,6 @@ impl Client {
}
#[cfg(feature = "debug")]
{

for rec in recs.iter() {
w.write_all(b"{\"data_type\":")?;
w.write_all(rec.data_type.to_string().as_bytes())?;
Expand All @@ -220,7 +156,7 @@ impl Client {
w.write_all(b"}\n")
}
Ok(())
}
}
}

pub fn send_records(&mut self, recs: &Vec<Record>) -> Result<(), Error> {
Expand Down
9 changes: 9 additions & 0 deletions plugins/lib/rust/src/sys/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#[cfg(target_family = "windows")]
pub mod windows;
#[cfg(target_family = "windows")]
pub use windows::*;

#[cfg(target_family = "unix")]
pub mod unix;
#[cfg(target_family = "unix")]
pub use unix::*;
61 changes: 61 additions & 0 deletions plugins/lib/rust/src/sys/unix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use std::os::unix::prelude::FromRawFd;

#[cfg(feature = "debug")]
const READ_PIPE_FD: i32 = 0;
#[cfg(not(feature = "debug"))]
const READ_PIPE_FD: i32 = 3;
#[cfg(feature = "debug")]
const WRITE_PIPE_FD: i32 = 1;
#[cfg(not(feature = "debug"))]
const WRITE_PIPE_FD: i32 = 4;
const HIGH_PRIORIT_FD: i32 = 5;

use std::{
fs::File,
io::{BufReader, BufWriter},
sync::Arc,
};

use parking_lot::Mutex;

pub fn get_writer() -> Arc<Mutex<BufWriter<File>>> {
Arc::new(Mutex::new(BufWriter::with_capacity(512 * 1024, unsafe {
File::from_raw_fd(WRITE_PIPE_FD)
})))
}

pub fn get_high_writer() -> Arc<Mutex<BufWriter<File>>> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里应该使用HIGH_PRIORIT_FD吧

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Arc::new(Mutex::new(BufWriter::with_capacity(512 * 1024, unsafe {
File::from_raw_fd(HIGH_PRIORIT_FD)
})))
}

pub fn get_reader() -> Arc<Mutex<BufReader<File>>> {
Arc::new(Mutex::new(BufReader::with_capacity(512 * 1024, unsafe {
File::from_raw_fd(READ_PIPE_FD)
})))
}

extern "C" fn signal_handler(signal: i32) {
eprintln!("catched signal {:?}, wait 3 seconds and exit", signal);
unsafe {
libc::sleep(3);
libc::close(WRITE_PIPE_FD);
libc::close(READ_PIPE_FD);
if libc::fcntl(HIGH_PRIORIT_FD, libc::F_GETFD) != -1
|| std::io::Error::last_os_error().kind() != std::io::ErrorKind::InvalidInput
{
libc::close(READ_PIPE_FD);
}
}
}

pub fn ignore_terminate() {
unsafe {
libc::signal(libc::SIGINT, libc::SIG_IGN);
libc::signal(libc::SIGUSR1, libc::SIG_IGN);
libc::signal(libc::SIGTERM, signal_handler as _);
}
}

pub fn regist_exception_handler() {}
Loading
Loading