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

feat: file create event #146

Merged
merged 2 commits into from
Nov 26, 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
2 changes: 2 additions & 0 deletions kunai-common/src/bpf_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ pub enum Type {
FileUnlink,
#[str("write_close")]
WriteClose,
#[str("file_create")]
FileCreate,

// specific userland events
// those should never be used in eBPF
Expand Down
9 changes: 6 additions & 3 deletions kunai-common/src/bpf_events/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,12 @@ const fn max_bpf_event_size() -> usize {
Type::Connect => ConnectEvent::size_of(),
Type::DnsQuery => DnsQueryEvent::size_of(),
Type::SendData => SendEntropyEvent::size_of(),
Type::Read | Type::ReadConfig | Type::Write | Type::WriteConfig | Type::WriteClose => {
FileEvent::size_of()
}
Type::Read
| Type::ReadConfig
| Type::Write
| Type::WriteConfig
| Type::WriteClose
| Type::FileCreate => FileEvent::size_of(),
Type::FileRename => FileRenameEvent::size_of(),
Type::FileUnlink => UnlinkEvent::size_of(),
Type::Error => ErrorEvent::size_of(),
Expand Down
4 changes: 4 additions & 0 deletions kunai-common/src/co_re/c/shim.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,15 @@ struct file
struct inode *f_inode;
struct path f_path;
void *private_data;
unsigned int f_flags;
unsigned int f_mode;
} __attribute__((preserve_access_index));

SHIM_REF(file, f_path);
SHIM(file, f_inode);
SHIM(file, private_data);
SHIM(file, f_flags);
SHIM(file, f_mode);

struct fd
{
Expand Down
2 changes: 2 additions & 0 deletions kunai-common/src/co_re/core_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ pub type file = CoRe<gen::file>;
impl file {
rust_shim_kernel_impl!(pub, file, f_path, path);
rust_shim_kernel_impl!(pub, file, f_inode, inode);
rust_shim_kernel_impl!(pub, file, f_flags, u32);
rust_shim_kernel_impl!(pub, file, f_mode, u32);

#[inline(always)]
pub unsafe fn is_file(&self) -> Option<bool> {
Expand Down
20 changes: 20 additions & 0 deletions kunai-common/src/co_re/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ pub struct file {
pub f_inode: *mut inode,
pub f_path: path,
pub private_data: *mut ::core::ffi::c_void,
pub f_flags: ::core::ffi::c_uint,
pub f_mode: ::core::ffi::c_uint,
}
extern "C" {
pub fn shim_file_f_path(file: *mut file) -> *mut path;
Expand Down Expand Up @@ -394,6 +396,24 @@ extern "C" {
extern "C" {
pub fn shim_file_private_data_exists(file: *mut file) -> bool;
}
extern "C" {
pub fn shim_file_f_flags(file: *mut file) -> ::core::ffi::c_uint;
}
extern "C" {
pub fn shim_file_f_flags_user(file: *mut file) -> ::core::ffi::c_uint;
}
extern "C" {
pub fn shim_file_f_flags_exists(file: *mut file) -> bool;
}
extern "C" {
pub fn shim_file_f_mode(file: *mut file) -> ::core::ffi::c_uint;
}
extern "C" {
pub fn shim_file_f_mode_user(file: *mut file) -> ::core::ffi::c_uint;
}
extern "C" {
pub fn shim_file_f_mode_exists(file: *mut file) -> bool;
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct fd {
Expand Down
42 changes: 42 additions & 0 deletions kunai-ebpf/src/probes/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,3 +447,45 @@ unsafe fn try_enter_fput(ctx: &ProbeContext) -> ProbeResult<()> {
// and re-write the file
file_unset_flag(&file, CLOSE_AFTER_WRITE)
}

const FMODE_CREATED: u32 = 0x100000;

// this probe aims at catching file creation event
#[kprobe(function = "security_file_open")]
pub fn fs_security_file_open(ctx: ProbeContext) -> u32 {
if is_current_loader_task() {
return 0;
}

match unsafe { try_security_file_open(&ctx) } {
Ok(_) => errors::BPF_PROG_SUCCESS,
Err(s) => {
error!(&ctx, s);
errors::BPF_PROG_FAILURE
}
}
}

unsafe fn try_security_file_open(ctx: &ProbeContext) -> ProbeResult<()> {
// if event is disabled we return
if_disabled_return!(Type::FileCreate, ());

let file = co_re::file::from_ptr(kprobe_arg!(ctx, 0)?);

// if not FMODE_CREATED we return
if !file.f_mode().unwrap_or_default() & FMODE_CREATED == FMODE_CREATED {
return Ok(());
}

alloc::init()?;
let e = alloc::alloc_zero::<FileEvent>()?;

e.init_from_current_task(Type::FileCreate)?;

e.data.path.core_resolve_file(&file, MAX_PATH_DEPTH)?;

// we send event
pipe_event(ctx, e);

Ok(())
}
22 changes: 13 additions & 9 deletions kunai/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1901,15 +1901,18 @@ impl<'s> EventConsumer<'s> {
Err(e) => error!("failed to decode {} event: {:?}", etype, e),
},

Type::WriteConfig | Type::Write | Type::ReadConfig | Type::Read | Type::WriteClose => {
match event!(enc_event, bpf_events::FileEvent) {
Ok(e) => {
let mut e = self.file_event(std_info, e);
self.scan_and_print(&mut e);
}
Err(e) => error!("failed to decode {} event: {:?}", etype, e),
Type::WriteConfig
| Type::Write
| Type::ReadConfig
| Type::Read
| Type::WriteClose
| Type::FileCreate => match event!(enc_event, bpf_events::FileEvent) {
Ok(e) => {
let mut e = self.file_event(std_info, e);
self.scan_and_print(&mut e);
}
}
Err(e) => error!("failed to decode {} event: {:?}", etype, e),
},

Type::FileUnlink => match event!(enc_event, bpf_events::UnlinkEvent) {
Ok(e) => {
Expand Down Expand Up @@ -2714,7 +2717,8 @@ impl Command {
| Type::Write
| Type::ReadConfig
| Type::Read
| Type::WriteClose => {
| Type::WriteClose
| Type::FileCreate => {
scan_event!(p, FileData)
}
Type::FileUnlink => scan_event!(p, UnlinkData),
Expand Down