Projects STRLCPY ebpfguard Commits 0430a91c
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■
    Cargo.toml
    skipped 6 lines
    7 7  ]
    8 8   
    9 9  [patch.crates-io]
    10  -aya = { git = "https://github.com/aya-rs/aya", branch = "main" }
     10 +aya = { git = "https://github.com/deepfence/aya-rs", branch = "btf-fixes" }
    11 11   
  • ■ ■ ■ ■
    ebpfguard/Cargo.toml
    skipped 3 lines
    4 4  edition = "2021"
    5 5   
    6 6  [dependencies]
    7  -aya = { git = "https://github.com/aya-rs/aya", branch = "main", features=["async_tokio"] }
     7 +aya = { git = "https://github.com/deepfence/aya-rs", branch = "btf-fixes", features=["async_tokio"] }
    8 8  bytes = "1.4"
    9 9  clap = { version = "4.2", features = ["derive"] }
    10 10  ebpfguard-common = { path = "../ebpfguard-common", features = ["user"] }
    skipped 13 lines
  • ■ ■ ■ ■ ■ ■
    ebpfguard-ebpf/Cargo.toml
    skipped 3 lines
    4 4  edition = "2021"
    5 5   
    6 6  [dependencies]
    7  -aya-bpf = { git = "https://github.com/aya-rs/aya", branch = "main" }
     7 +aya-bpf = { git = "https://github.com/deepfence/aya-rs", branch = "btf-fixes" }
    8 8  ebpfguard-common = { path = "../ebpfguard-common" }
    9 9   
    10 10  [build-dependencies]
    11  -aya-tool = { git = "https://github.com/aya-rs/aya", branch = "main" }
     11 +aya-tool = { git = "https://github.com/deepfence/aya-rs", branch = "btf-fixes" }
    12 12   
    13 13  [lib]
    14 14  name = "ebpfguard_ebpf"
    skipped 24 lines
  • ■ ■ ■ ■ ■
    ebpfguard-ebpf/build.rs
    skipped 2 lines
    3 3   fs::File,
    4 4   io::Write,
    5 5   path::{Path, PathBuf},
     6 + process::Command,
    6 7  };
    7 8   
    8 9  use aya_tool::generate::InputFile;
    9 10   
    10 11  fn main() {
    11  - let out_dir = env::var_os("OUT_DIR").unwrap();
     12 + println!("cargo:rerun-if-changed=build.rs");
     13 + 
     14 + let out_dir = env::var("OUT_DIR").unwrap();
    12 15   let dest_path = Path::new(&out_dir).join("vmlinux.rs");
    13 16   
    14 17   let names: Vec<&str> = vec![
    skipped 12 lines
    27 30   )
    28 31   .unwrap();
    29 32   
    30  - let mut out = File::create(&dest_path).unwrap();
     33 + let mut out = File::create(dest_path).unwrap();
    31 34   write!(out, "{}", bindings).unwrap();
    32 35   
    33  - println!("cargo:rerun-if-changed=build.rs");
     36 + let _ = Command::new("clang")
     37 + .arg("-I")
     38 + .arg("src/")
     39 + .arg("-O2")
     40 + .arg("-emit-llvm")
     41 + .arg("-target")
     42 + .arg("bpf")
     43 + .arg("-c")
     44 + .arg("-g")
     45 + .arg("src/vmlinux_access.c")
     46 + .arg("-o")
     47 + .arg(format!("{out_dir}/vmlinux_access.o"))
     48 + .status()
     49 + .expect("Failed to compile the C-shim");
     50 + 
     51 + println!("cargo:rustc-link-search=native={out_dir}");
     52 + println!("cargo:rustc-link-lib=link-arg={out_dir}/vmlinux_access.o");
     53 + println!("cargo:rerun-if-changed=src/vmlinux_access.c");
    34 54  }
    35 55   
  • ■ ■ ■ ■ ■ ■
    ebpfguard-ebpf/src/binprm.rs
    skipped 2 lines
    3 3   helpers::{bpf_get_current_task, bpf_probe_read_kernel},
    4 4  };
    5 5   
    6  -use crate::vmlinux::task_struct;
     6 +use crate::{exe_file_inode, inode_i_ino, mm_exe_file, task_struct_mm, vmlinux::task_struct};
    7 7   
    8 8  /// Returns the inode of the current binary.
    9 9  ///
    skipped 11 lines
    21 21  pub(crate) fn current_binprm_inode() -> Result<u64, c_long> {
    22 22   let binprm_inode = unsafe {
    23 23   let task = bpf_get_current_task() as *mut task_struct;
    24  - let mm = bpf_probe_read_kernel(&(*task).mm)?;
    25  - let file = bpf_probe_read_kernel(&(*mm).__bindgen_anon_1.exe_file)?;
    26  - let f_inode = bpf_probe_read_kernel(&(*file).f_inode)?;
    27  - bpf_probe_read_kernel(&(*f_inode).i_ino)?
     24 + let mm = bpf_probe_read_kernel(task_struct_mm(task))?;
     25 + let file = bpf_probe_read_kernel(mm_exe_file(mm))?;
     26 + let f_inode = bpf_probe_read_kernel(exe_file_inode(file))?;
     27 + bpf_probe_read_kernel(inode_i_ino(f_inode))?
    28 28   };
    29 29   Ok(binprm_inode)
    30 30  }
    skipped 1 lines
  • ■ ■ ■ ■ ■ ■
    ebpfguard-ebpf/src/bprm_check_security.rs
    1 1  use aya_bpf::{cty::c_long, programs::LsmContext, BpfContext};
    2 2  use ebpfguard_common::alerts;
    3 3   
    4  -use crate::{binprm::current_binprm_inode, maps::ALERT_BPRM_CHECK_SECURITY, vmlinux::linux_binprm};
     4 +use crate::{
     5 + binprm::current_binprm_inode, linux_binprm_argc, maps::ALERT_BPRM_CHECK_SECURITY,
     6 + vmlinux::linux_binprm,
     7 +};
    5 8   
    6 9  pub fn bprm_check_security(ctx: LsmContext) -> Result<i32, c_long> {
    7 10   let new_binprm: *const linux_binprm = unsafe { ctx.arg(0) };
    8  - let argc = unsafe { (*new_binprm).argc };
     11 + let argc = unsafe { linux_binprm_argc(new_binprm) };
    9 12   
    10 13   let old_binprm_inode = current_binprm_inode()?;
    11 14   
    skipped 12 lines
  • ■ ■ ■ ■ ■ ■
    ebpfguard-ebpf/src/file_open.rs
    skipped 6 lines
    7 7   
    8 8  use crate::{
    9 9   binprm::current_binprm_inode,
     10 + dentry_i_ino, file_dentry, file_inode,
    10 11   maps::{ALERT_FILE_OPEN, ALLOWED_FILE_OPEN, DENIED_FILE_OPEN},
    11 12   vmlinux::file,
    12 13   Action, Mode,
    skipped 22 lines
    35 36   let file: *const file = unsafe { ctx.arg(0) };
    36 37   
    37 38   let binprm_inode = current_binprm_inode()?;
    38  - let inode = unsafe { (*(*(*file).f_path.dentry).d_inode).i_ino };
     39 + let inode = unsafe { file_inode(file) };
    39 40   
    40 41   if let Some(paths) = unsafe { ALLOWED_FILE_OPEN.get(&INODE_WILDCARD) } {
    41 42   if paths.paths[0] == 0 {
    skipped 103 lines
    145 146   mut previous_inode: u64,
    146 147   mode: &Mode,
    147 148  ) -> Option<Action> {
    148  - let mut parent_dentry = unsafe { (*(*file).f_path.dentry).d_parent };
     149 + let mut parent_dentry = unsafe { file_dentry(file) };
    149 150   for _ in 0..MAX_DIR_DEPTH {
    150 151   if parent_dentry.is_null() {
    151 152   break;
    152 153   }
    153  - let inode = unsafe { (*(*parent_dentry).d_inode).i_ino };
     154 + let inode = unsafe { dentry_i_ino(parent_dentry) };
    154 155   if inode == previous_inode {
    155 156   break;
    156 157   }
    skipped 13 lines
  • ■ ■ ■ ■ ■ ■
    ebpfguard-ebpf/src/lib.rs
    1 1  #![no_std]
     2 +#![no_main]
    2 3   
    3 4  pub mod binprm;
    4 5  pub mod bprm_check_security;
    skipped 11 lines
    16 17  #[allow(non_camel_case_types)]
    17 18  #[allow(dead_code)]
    18 19  pub mod vmlinux;
     20 + 
     21 +use aya_bpf::cty::{c_ushort, c_void};
     22 +use aya_bpf::{cty::c_int, cty::c_uint, cty::c_ulong};
     23 + 
     24 +use vmlinux::cred;
     25 +use vmlinux::dentry;
     26 +use vmlinux::file;
     27 +use vmlinux::inode;
     28 +use vmlinux::linux_binprm;
     29 +use vmlinux::mm_struct;
     30 +use vmlinux::sockaddr;
     31 +use vmlinux::sockaddr_in;
     32 +use vmlinux::sockaddr_in6;
     33 +use vmlinux::task_struct;
     34 + 
     35 +#[allow(improper_ctypes)]
     36 +extern "C" {
     37 + fn cred_gid_val(target: *const cred) -> c_uint;
     38 + fn cred_uid_val(target: *const cred) -> c_uint;
     39 + fn dentry_i_ino(target: *const dentry) -> c_ulong;
     40 + fn exe_file_inode(target: *const file) -> *const *const inode;
     41 + fn file_dentry(target: *const file) -> *const dentry;
     42 + fn file_inode(target: *const file) -> c_ulong;
     43 + fn inode_i_ino(inode: *const inode) -> *const c_ulong;
     44 + fn linux_binprm_argc(task: *const linux_binprm) -> c_int;
     45 + fn mm_exe_file(target: *const mm_struct) -> *const *const file;
     46 + fn sockaddr_in_sin_addr_s_addr(task: *const sockaddr_in) -> c_uint;
     47 + fn sockaddr_in_sin_port(target: *const sockaddr_in) -> c_ushort;
     48 + fn sockaddr_sa_family(task: *const sockaddr) -> c_ushort;
     49 + fn sockaddr_in6_sin6_addr_in6_u_u6_addr8(
     50 + sockaddr: *const sockaddr_in6,
     51 + array: &[u8; 16],
     52 + ) -> c_void;
     53 + fn task_struct_mm(target: *const task_struct) -> *const *const mm_struct;
     54 +}
    19 55   
    20 56  pub enum Mode {
    21 57   Allowlist,
    skipped 17 lines
  • ■ ■ ■ ■ ■
    ebpfguard-ebpf/src/socket_bind.rs
    skipped 4 lines
    5 5   binprm::current_binprm_inode,
    6 6   consts::AF_INET,
    7 7   maps::{ALERT_SOCKET_BIND, ALLOWED_SOCKET_BIND, DENIED_SOCKET_BIND},
     8 + sockaddr_in_sin_port, sockaddr_sa_family,
    8 9   vmlinux::{sockaddr, sockaddr_in},
    9 10   Action,
    10 11  };
    skipped 22 lines
    33 34  pub fn socket_bind(ctx: LsmContext) -> Result<Action, c_long> {
    34 35   let sockaddr: *const sockaddr = unsafe { ctx.arg(1) };
    35 36   
    36  - if unsafe { (*sockaddr).sa_family } != AF_INET {
     37 + if unsafe { sockaddr_sa_family(sockaddr) } != AF_INET {
    37 38   return Ok(Action::Allow);
    38 39   }
    39 40   
    40 41   let sockaddr_in: *const sockaddr_in = sockaddr as *const sockaddr_in;
    41  - let port = u16::from_be(unsafe { (*sockaddr_in).sin_port });
     42 + let port = u16::from_be(unsafe { sockaddr_in_sin_port(sockaddr_in) });
    42 43   
    43 44   if port == 0 {
    44 45   return Ok(Action::Allow);
    skipped 91 lines
  • ■ ■ ■ ■ ■ ■
    ebpfguard-ebpf/src/socket_connect.rs
    skipped 13 lines
    14 14   ALERT_SOCKET_CONNECT, ALLOWED_SOCKET_CONNECT_V4, ALLOWED_SOCKET_CONNECT_V6,
    15 15   DENIED_SOCKET_CONNECT_V4, DENIED_SOCKET_CONNECT_V6,
    16 16   },
     17 + sockaddr_in6_sin6_addr_in6_u_u6_addr8, sockaddr_in_sin_addr_s_addr, sockaddr_sa_family,
    17 18   vmlinux::{sockaddr, sockaddr_in, sockaddr_in6},
    18 19   Action, Mode,
    19 20  };
    skipped 19 lines
    39 40  /// ```
    40 41  pub fn socket_connect(ctx: LsmContext) -> Result<Action, c_long> {
    41 42   let sockaddr: *const sockaddr = unsafe { ctx.arg(1) };
    42  - let sa_family = unsafe { (*sockaddr).sa_family };
     43 + let sa_family = unsafe { sockaddr_sa_family(sockaddr) };
    43 44   
    44 45   match sa_family {
    45 46   AF_INET => socket_connect_v4(ctx, sockaddr),
    skipped 5 lines
    51 52  #[inline(always)]
    52 53  fn socket_connect_v4(ctx: LsmContext, sockaddr: *const sockaddr) -> Result<Action, c_long> {
    53 54   let sockaddr_in: *const sockaddr_in = sockaddr as *const sockaddr_in;
    54  - let addr = u32::from_be(unsafe { (*sockaddr_in).sin_addr.s_addr });
     55 + let addr = u32::from_be(unsafe { sockaddr_in_sin_addr_s_addr(sockaddr_in) });
    55 56   
    56 57   let binprm_inode = current_binprm_inode()?;
    57 58   
    skipped 29 lines
    87 88   let sockaddr_in6: *const sockaddr_in6 = sockaddr as *const sockaddr_in6;
    88 89   
    89 90   let sockaddr_in6: sockaddr_in6 = unsafe { bpf_probe_read_kernel(sockaddr_in6)? };
    90  - let addr = unsafe { sockaddr_in6.sin6_addr.in6_u.u6_addr8 };
     91 + let addr: [u8; 16] = [0; 16];
     92 + unsafe { sockaddr_in6_sin6_addr_in6_u_u6_addr8(&sockaddr_in6, &addr) };
    91 93   
    92 94   let binprm_inode = current_binprm_inode()?;
    93 95   
    skipped 121 lines
  • ■ ■ ■ ■ ■ ■
    ebpfguard-ebpf/src/task_fix_setuid.rs
    skipped 2 lines
    3 3   
    4 4  use crate::{
    5 5   binprm::current_binprm_inode,
     6 + cred_gid_val, cred_uid_val,
    6 7   maps::{ALERT_TASK_FIX_SETUID, ALLOWED_TASK_FIX_SETUID, DENIED_TASK_FIX_SETUID},
    7 8   vmlinux::cred,
    8 9  };
    skipped 21 lines
    30 31   let new: *const cred = unsafe { ctx.arg(0) };
    31 32   let old: *const cred = unsafe { ctx.arg(1) };
    32 33   
    33  - let old_uid = unsafe { (*old).uid.val };
    34  - let old_gid = unsafe { (*old).gid.val };
    35  - let new_uid = unsafe { (*new).uid.val };
    36  - let new_gid = unsafe { (*new).gid.val };
     34 + let old_uid = unsafe { cred_uid_val(old) };
     35 + let old_gid = unsafe { cred_gid_val(old) };
     36 + let new_uid = unsafe { cred_uid_val(new) };
     37 + let new_gid = unsafe { cred_gid_val(new) };
    37 38   
    38 39   let binprm_inode = current_binprm_inode()?;
    39 40   
    skipped 41 lines
  • ebpfguard-ebpf/src/vmlinux.h
    Unable to diff as the file is too large.
  • ■ ■ ■ ■ ■ ■
    ebpfguard-ebpf/src/vmlinux_access.c
     1 +#include "vmlinux.h"
     2 + 
     3 +pid_t task_struct_pid(struct task_struct *task)
     4 +{
     5 + return __builtin_preserve_access_index(task->pid);
     6 +}
     7 + 
     8 +pid_t task_struct_tgid(struct task_struct *task)
     9 +{
     10 + return __builtin_preserve_access_index(task->tgid);
     11 +}
     12 + 
     13 +struct mm_struct ** task_struct_mm(struct task_struct *task)
     14 +{
     15 + return __builtin_preserve_access_index(&task->mm);
     16 +}
     17 + 
     18 +struct file ** mm_exe_file(struct mm_struct *target)
     19 +{
     20 + return __builtin_preserve_access_index(&target->exe_file);
     21 +}
     22 + 
     23 +struct inode ** exe_file_inode(struct file *target)
     24 +{
     25 + return __builtin_preserve_access_index(&target->f_inode);
     26 +}
     27 + 
     28 +uint64_t file_inode(struct file *target)
     29 +{
     30 + return __builtin_preserve_access_index(target->f_path.dentry->d_inode->i_ino);
     31 +}
     32 + 
     33 +struct dentry* file_dentry(struct file *target)
     34 +{
     35 + return __builtin_preserve_access_index(target->f_path.dentry->d_parent);
     36 +}
     37 + 
     38 +uint64_t dentry_i_ino(struct dentry *target)
     39 +{
     40 + return __builtin_preserve_access_index(target->d_inode->i_ino);
     41 +}
     42 + 
     43 +uint64_t * inode_i_ino(struct inode *inode)
     44 +{
     45 + return __builtin_preserve_access_index(&inode->i_ino);
     46 +}
     47 + 
     48 +int32_t linux_binprm_argc(struct linux_binprm *target)
     49 +{
     50 + return __builtin_preserve_access_index(target->argc);
     51 +}
     52 + 
     53 +int16_t sockaddr_sa_family(struct sockaddr *target)
     54 +{
     55 + return __builtin_preserve_access_index(target->sa_family);
     56 +}
     57 + 
     58 +uint32_t sockaddr_in_sin_addr_s_addr(struct sockaddr_in *target)
     59 +{
     60 + return __builtin_preserve_access_index(target->sin_addr.s_addr);
     61 +}
     62 + 
     63 +void sockaddr_in6_sin6_addr_in6_u_u6_addr8(struct sockaddr_in6 *target, uint8_t* res)
     64 +{
     65 + for (int i=0; i < 16; ++i) {
     66 + res[i] = __builtin_preserve_access_index(target->sin6_addr.in6_u.u6_addr8[i]);
     67 + }
     68 +}
     69 + 
     70 +uid_t cred_uid_val(struct cred *target)
     71 +{
     72 + return __builtin_preserve_access_index(target->uid.val);
     73 +}
     74 + 
     75 +uid_t cred_gid_val(struct cred *target)
     76 +{
     77 + return __builtin_preserve_access_index(target->gid.val);
     78 +}
     79 + 
     80 +uint16_t sockaddr_in_sin_port(struct sockaddr_in *target)
     81 +{
     82 + return __builtin_preserve_access_index(target->sin_port);
     83 +}
     84 + 
Please wait...
Page is in error, reload to recover