Projects STRLCPY ebpfguard Commits 4f15152f
🤬
  • Separate eBPF and user space alert structures

    `#[repr(C)]` structs compatible with eBPF (with padding fields) are too
    inconvenient for the end users in user space. It's better to keep the
    definitions separate and use the `From` trait to convert.
    
    Also, remove serde and anyhow from the common crate.
  • Loading...
  • Michal Rostecki committed with vadorovsky 1 year ago
    4f15152f
    1 parent 1423ad2f
  • ■ ■ ■ ■ ■ ■
    guardity/src/alerts.rs
     1 +use guardity_common::alerts;
     2 +use std::{
     3 + net::{IpAddr, Ipv4Addr, Ipv6Addr},
     4 + path::PathBuf,
     5 +};
     6 + 
     7 +use crate::policy::PolicySubject;
     8 + 
     9 +pub trait Alert {}
     10 + 
     11 +#[derive(Debug)]
     12 +pub struct BprmCheckSecurity {
     13 + pub pid: u32,
     14 + pub subject: PolicySubject,
     15 +}
     16 + 
     17 +impl Alert for BprmCheckSecurity {}
     18 + 
     19 +impl From<alerts::BprmCheckSecurity> for BprmCheckSecurity {
     20 + fn from(alert: alerts::BprmCheckSecurity) -> Self {
     21 + Self {
     22 + pid: alert.pid,
     23 + subject: PolicySubject::Process(PathBuf::from(alert.binprm_inode.to_string())),
     24 + }
     25 + }
     26 +}
     27 + 
     28 +#[derive(Debug)]
     29 +pub struct FileOpen {
     30 + pub pid: u32,
     31 + pub subject: PolicySubject,
     32 + pub path: PathBuf,
     33 +}
     34 + 
     35 +impl Alert for FileOpen {}
     36 + 
     37 +impl From<alerts::FileOpen> for FileOpen {
     38 + fn from(alert: alerts::FileOpen) -> Self {
     39 + Self {
     40 + pid: alert.pid,
     41 + subject: PolicySubject::Process(PathBuf::from(alert.binprm_inode.to_string())),
     42 + path: PathBuf::from(alert.inode.to_string()),
     43 + }
     44 + }
     45 +}
     46 + 
     47 +#[derive(Debug)]
     48 +pub struct TaskFixSetUid {
     49 + pub pid: u32,
     50 + pub subject: PolicySubject,
     51 + pub old_uid: u32,
     52 + pub old_gid: u32,
     53 + pub new_uid: u32,
     54 + pub new_gid: u32,
     55 +}
     56 + 
     57 +impl Alert for TaskFixSetUid {}
     58 + 
     59 +impl From<alerts::TaskFixSetuid> for TaskFixSetUid {
     60 + fn from(alert: alerts::TaskFixSetuid) -> Self {
     61 + Self {
     62 + pid: alert.pid,
     63 + subject: PolicySubject::Process(PathBuf::from(alert.binprm_inode.to_string())),
     64 + old_uid: alert.old_uid,
     65 + old_gid: alert.old_gid,
     66 + new_uid: alert.new_uid,
     67 + new_gid: alert.new_gid,
     68 + }
     69 + }
     70 +}
     71 + 
     72 +#[derive(Debug)]
     73 +pub struct SocketBind {
     74 + pub pid: u32,
     75 + pub subject: PolicySubject,
     76 + pub port: u16,
     77 +}
     78 + 
     79 +impl Alert for SocketBind {}
     80 + 
     81 +impl From<alerts::SocketBind> for SocketBind {
     82 + fn from(alert: alerts::SocketBind) -> Self {
     83 + Self {
     84 + pid: alert.pid,
     85 + subject: PolicySubject::Process(PathBuf::from(alert.binprm_inode.to_string())),
     86 + port: alert.port,
     87 + }
     88 + }
     89 +}
     90 + 
     91 +#[derive(Debug)]
     92 +pub struct SocketConnect {
     93 + pub pid: u32,
     94 + pub subject: PolicySubject,
     95 + pub addr: IpAddr,
     96 +}
     97 + 
     98 +impl Alert for SocketConnect {}
     99 + 
     100 +impl From<alerts::SocketConnect> for SocketConnect {
     101 + fn from(alert: alerts::SocketConnect) -> Self {
     102 + let addr = if alert.addr_v4 != 0 {
     103 + IpAddr::V4(Ipv4Addr::from(alert.addr_v4))
     104 + } else {
     105 + IpAddr::V6(Ipv6Addr::from(alert.addr_v6))
     106 + };
     107 + Self {
     108 + pid: alert.pid,
     109 + subject: PolicySubject::Process(PathBuf::from(alert.binprm_inode.to_string())),
     110 + addr,
     111 + }
     112 + }
     113 +}
     114 + 
  • ■ ■ ■ ■ ■ ■
    guardity/src/lib.rs
    skipped 7 lines
    8 8   Bpf, BpfLoader, Btf,
    9 9  };
    10 10  use bytes::BytesMut;
    11  -use guardity_common::{
    12  - Alert, AlertBprmCheckSecurity, AlertFileOpen, AlertSetuid, AlertSocketBind, AlertSocketConnect,
    13  -};
     11 +use guardity_common::alerts as ebpf_alerts;
    14 12  use tokio::{
    15 13   sync::mpsc::{self, Receiver},
    16 14   task,
    17 15  };
    18 16   
     17 +pub mod alerts;
    19 18  pub mod fs;
    20 19  pub mod policy;
    21 20   
    skipped 127 lines
    149 148   Ok(perf_array)
    150 149  }
    151 150   
    152  -pub struct Hook<T>
     151 +pub struct Hook<T, U>
    153 152  where
    154  - T: Alert,
     153 + T: ebpf_alerts::Alert,
     154 + U: alerts::Alert,
    155 155  {
    156 156   #[allow(dead_code)]
    157 157   program_link: LsmLink,
    158 158   perf_array: AsyncPerfEventArray<MapData>,
    159  - phantom: PhantomData<T>,
     159 + phantom_t: PhantomData<T>,
     160 + phantom_u: PhantomData<U>,
    160 161  }
    161 162   
    162  -impl<T> Hook<T>
     163 +impl<T, U> Hook<T, U>
    163 164  where
    164  - T: Alert + Debug + Send + 'static,
     165 + T: ebpf_alerts::Alert,
     166 + U: alerts::Alert + Debug + Send + From<T> + 'static,
    165 167  {
    166 168   fn new(
    167 169   program_link: LsmLink,
    skipped 2 lines
    170 172   Ok(Self {
    171 173   program_link,
    172 174   perf_array,
    173  - phantom: PhantomData,
     175 + phantom_t: PhantomData,
     176 + phantom_u: PhantomData,
    174 177   })
    175 178   }
    176 179   
    177  - pub async fn alerts(&mut self) -> anyhow::Result<Receiver<T>> {
     180 + pub async fn alerts(&mut self) -> anyhow::Result<Receiver<U>> {
    178 181   let (tx, rx) = mpsc::channel(32);
    179 182   
    180 183   let cpus = online_cpus()?;
    skipped 8 lines
    189 192   loop {
    190 193   let events = buf.read_events(&mut buffers).await.unwrap();
    191 194   for buf in buffers.iter_mut().take(events.read) {
    192  - let alert = {
     195 + let alert: U = {
    193 196   let ptr = buf.as_ptr() as *const T;
    194  - unsafe { ptr.read_unaligned() }
     197 + let alert = unsafe { ptr.read_unaligned() };
     198 + alert.into()
    195 199   };
    196 200   tx.send(alert).await.unwrap();
    197 201   }
    skipped 5 lines
    203 207   }
    204 208  }
    205 209   
    206  -pub type BprmCheckSecurityHook = Hook<AlertBprmCheckSecurity>;
    207  -pub type FileOpenHook = Hook<AlertFileOpen>;
    208  -pub type TaskFixSetuidHook = Hook<AlertSetuid>;
    209  -pub type SocketBindHook = Hook<AlertSocketBind>;
    210  -pub type SocketConnectHook = Hook<AlertSocketConnect>;
     210 +pub type BprmCheckSecurityHook = Hook<ebpf_alerts::BprmCheckSecurity, alerts::BprmCheckSecurity>;
     211 +pub type FileOpenHook = Hook<ebpf_alerts::FileOpen, alerts::FileOpen>;
     212 +pub type TaskFixSetuidHook = Hook<ebpf_alerts::TaskFixSetuid, alerts::TaskFixSetUid>;
     213 +pub type SocketBindHook = Hook<ebpf_alerts::SocketBind, alerts::SocketBind>;
     214 +pub type SocketConnectHook = Hook<ebpf_alerts::SocketConnect, alerts::SocketConnect>;
    211 215   
  • ■ ■ ■ ■ ■ ■
    guardity/src/main.rs
    skipped 49 lines
    50 50   info!("file_open: {}", alert.pid);
    51 51   }
    52 52   Some(alert) = rx_task_fix_setuid.recv() => {
    53  - info!("task_fix_setuid: pid={} binprm_inode={}", alert.pid, alert.binprm_inode);
     53 + info!("task_fix_setuid: pid={} binprm_inode={}", alert.pid, alert.subject);
    54 54   }
    55 55   Some(alert) = rx_socket_bind.recv() => {
    56 56   info!("socket_bind: pid={}", alert.pid);
    57 57   }
    58 58   Some(alert) = rx_socket_connect.recv() => {
    59  - if alert.addr_v4 != 0 {
    60  - info!(
    61  - "socket_connect: pid={} binprm_inode={} addr={}",
    62  - alert.pid,
    63  - alert.binprm_inode,
    64  - alert.addr_v4
    65  - );
    66  - } else {
    67  - info!(
    68  - "socket_connect: pid={} binprm_inode={} addr={:?}",
    69  - alert.pid,
    70  - alert.binprm_inode,
    71  - alert.addr_v6
    72  - );
    73  - }
     59 + info!(
     60 + "socket_connect: pid={} binprm_inode={} addr={}",
     61 + alert.pid,
     62 + alert.subject,
     63 + alert.addr
     64 + );
    74 65   }
    75 66   _ = signal::ctrl_c() => {
    76 67   break;
    skipped 9 lines
  • ■ ■ ■ ■ ■ ■
    guardity/src/policy/engine.rs
    skipped 26 lines
    27 27   bpf.map_mut("DENIED_FILE_OPEN").unwrap().try_into()?;
    28 28   denied_file_open.insert(bin_inode, deny, 0)?;
    29 29   }
    30  - PolicySubject::Container(_) => {
    31  - unimplemented!();
    32  - }
    33 30   PolicySubject::All => {
    34 31   let mut allowed_file_open: HashMap<_, u64, Paths> =
    35 32   bpf.map_mut("ALLOWED_FILE_OPEN").unwrap().try_into()?;
    skipped 18 lines
    54 51   bpf.map_mut("DENIED_SETUID").unwrap().try_into()?;
    55 52   denied_setuid.insert(inode, 0, 0)?;
    56 53   }
    57  - }
    58  - PolicySubject::Container(_) => {
    59  - unimplemented!();
    60 54   }
    61 55   PolicySubject::All => {
    62 56   if allow {
    skipped 26 lines
    89 83   bpf.map_mut("DENIED_SOCKET_BIND").unwrap().try_into()?;
    90 84   denied_socket_bind.insert(inode, deny, 0)?;
    91 85   }
    92  - PolicySubject::Container(_) => {
    93  - unimplemented!();
    94  - }
    95 86   PolicySubject::All => {
    96 87   let mut allowed_socket_bind: HashMap<_, u64, Ports> =
    97 88   bpf.map_mut("ALLOWED_SOCKET_BIND").unwrap().try_into()?;
    skipped 39 lines
    137 128   .unwrap()
    138 129   .try_into()?;
    139 130   denied_socket_connect_v6.insert(bin_inode, deny_v6, 0)?;
    140  - }
    141  - PolicySubject::Container(_) => {
    142  - unimplemented!();
    143 131   }
    144 132   PolicySubject::All => {
    145 133   let mut allowed_socket_connect_v4: HashMap<_, u64, Ipv4Addrs> = bpf
    skipped 29 lines
  • ■ ■ ■ ■ ■ ■
    guardity/src/policy/mod.rs
    1  -use std::{net::IpAddr, path::PathBuf};
     1 +use std::{
     2 + fmt::{Display, Formatter},
     3 + net::IpAddr,
     4 + path::PathBuf,
     5 +};
    2 6   
    3 7  use serde::{Deserialize, Serialize};
    4 8   
    skipped 6 lines
    11 15  pub enum PolicySubject {
    12 16   #[serde(rename = "process")]
    13 17   Process(PathBuf),
    14  - #[serde(rename = "container")]
    15  - Container(String),
    16 18   #[serde(rename = "all")]
    17 19   All,
    18 20  }
    19 21   
     22 +impl Display for PolicySubject {
     23 + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
     24 + match self {
     25 + PolicySubject::Process(path) => write!(f, "{}", path.display()),
     26 + PolicySubject::All => write!(f, "all"),
     27 + }
     28 + }
     29 +}
     30 + 
    20 31  #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
    21 32  pub enum Paths {
    22 33   #[serde(rename = "all")]
    skipped 14 lines
    37 48   match self {
    38 49   Paths::All => guardity_common::Paths {
    39 50   paths: [0; guardity_common::MAX_PATHS],
    40  - // len: 0,
    41  - // all: 1,
    42  - // _padding: [0; 7],
    43 51   },
    44 52   Paths::Paths(paths) => {
    45 53   let mut ebpf_paths = [0; guardity_common::MAX_PATHS];
    46 54   for (i, path) in paths.iter().enumerate() {
    47 55   ebpf_paths[i] = fs::inode(path).unwrap();
    48 56   }
    49  - guardity_common::Paths {
    50  - paths: ebpf_paths,
    51  - // len: paths.len(),
    52  - // all: 0,
    53  - // _padding: [0; 7],
    54  - }
     57 + guardity_common::Paths { paths: ebpf_paths }
    55 58   }
    56 59   }
    57 60   }
    skipped 135 lines
    193 196   allow: !paths
    194 197   - /etc/myapp
    195 198   deny: all
    196  -- !file_open
    197  - subject: !container docker.io/myapp
    198  - allow: !paths
    199  - - /etc/myapp
    200  - deny: all
    201 199  ";
    202 200   let policy = serde_yaml::from_str::<Vec<Policy>>(yaml).unwrap();
    203  - assert_eq!(policy.len(), 3);
     201 + assert_eq!(policy.len(), 2);
    204 202   assert_eq!(
    205 203   policy[0],
    206 204   Policy::FileOpen {
    skipped 10 lines
    217 215   deny: Paths::All
    218 216   }
    219 217   );
    220  - assert_eq!(
    221  - policy[2],
    222  - Policy::FileOpen {
    223  - subject: PolicySubject::Container("docker.io/myapp".to_string()),
    224  - allow: Paths::Paths(vec![PathBuf::from("/etc/myapp")]),
    225  - deny: Paths::All
    226  - }
    227  - );
    228 218   }
    229 219   
    230 220   #[test]
    skipped 5 lines
    236 226  - !setuid
    237 227   subject: !process /usr/bin/sudo
    238 228   allow: true
    239  -- !setuid
    240  - subject: !container deepfenceio/deepfence_agent_ce
    241  - allow: true
    242 229  ";
    243 230   let policy = serde_yaml::from_str::<Vec<Policy>>(yaml).unwrap();
    244  - assert_eq!(policy.len(), 3);
     231 + assert_eq!(policy.len(), 2);
    245 232   assert_eq!(
    246 233   policy[0],
    247 234   Policy::SetUid {
    skipped 8 lines
    256 243   allow: true
    257 244   }
    258 245   );
    259  - assert_eq!(
    260  - policy[2],
    261  - Policy::SetUid {
    262  - subject: PolicySubject::Container("deepfenceio/deepfence_agent_ce".to_string()),
    263  - allow: true
    264  - }
    265  - );
    266 246   }
    267 247   
    268 248   #[test]
    skipped 10 lines
    279 259   allow: !ports
    280 260   - 8080
    281 261   deny: all
    282  -- !socket_bind
    283  - subject: !container docker.io/nginx
    284  - allow: !ports
    285  - - 80
    286  - - 443
    287  - deny: all
    288 262  ";
    289 263   let policy = serde_yaml::from_str::<Vec<Policy>>(yaml).unwrap();
    290  - assert_eq!(policy.len(), 3);
     264 + assert_eq!(policy.len(), 2);
    291 265   assert_eq!(
    292 266   policy[0],
    293 267   Policy::SocketBind {
    skipped 10 lines
    304 278   deny: Ports::All
    305 279   }
    306 280   );
    307  - assert_eq!(
    308  - policy[2],
    309  - Policy::SocketBind {
    310  - subject: PolicySubject::Container("docker.io/nginx".to_string()),
    311  - allow: Ports::Ports(vec![80, 443]),
    312  - deny: Ports::All
    313  - }
    314  - )
    315 281   }
    316 282   
    317 283   #[test]
    skipped 46 lines
  • ■ ■ ■ ■ ■
    guardity-common/Cargo.toml
    skipped 4 lines
    5 5   
    6 6  [features]
    7 7  default = []
    8  -user = ["anyhow", "aya", "serde"]
     8 +user = ["aya"]
    9 9   
    10 10  [dependencies]
    11  -anyhow = { version = "1.0", optional = true }
    12 11  aya = { version = ">=0.11", optional = true }
    13  -serde = { version = "1.0", features = ["derive"], optional = true }
    14 12   
    15 13  [lib]
    16 14  path = "src/lib.rs"
    skipped 1 lines
  • ■ ■ ■ ■ ■ ■
    guardity-common/src/alerts.rs
     1 +pub trait Alert {}
     2 + 
     3 +#[repr(C)]
     4 +#[derive(Copy, Clone)]
     5 +pub struct BprmCheckSecurity {
     6 + pub pid: u32,
     7 + _padding: u32,
     8 + pub binprm_inode: u64,
     9 +}
     10 + 
     11 +impl BprmCheckSecurity {
     12 + pub fn new(pid: u32, binprm_inode: u64) -> Self {
     13 + Self {
     14 + pid,
     15 + _padding: 0,
     16 + binprm_inode,
     17 + }
     18 + }
     19 +}
     20 + 
     21 +impl Alert for BprmCheckSecurity {}
     22 + 
     23 +#[repr(C)]
     24 +#[derive(Copy, Clone)]
     25 +pub struct FileOpen {
     26 + pub pid: u32,
     27 + _padding: u32,
     28 + pub binprm_inode: u64,
     29 + pub inode: u64,
     30 +}
     31 + 
     32 +impl FileOpen {
     33 + pub fn new(pid: u32, binprm_inode: u64, inode: u64) -> Self {
     34 + Self {
     35 + pid,
     36 + _padding: 0,
     37 + binprm_inode,
     38 + inode,
     39 + }
     40 + }
     41 +}
     42 + 
     43 +impl Alert for FileOpen {}
     44 + 
     45 +#[repr(C)]
     46 +#[derive(Copy, Clone)]
     47 +pub struct TaskFixSetuid {
     48 + pub pid: u32,
     49 + _padding: u32,
     50 + pub binprm_inode: u64,
     51 + pub old_uid: u32,
     52 + pub old_gid: u32,
     53 + pub new_uid: u32,
     54 + pub new_gid: u32,
     55 +}
     56 + 
     57 +impl TaskFixSetuid {
     58 + pub fn new(
     59 + pid: u32,
     60 + binprm_inode: u64,
     61 + old_uid: u32,
     62 + old_gid: u32,
     63 + new_uid: u32,
     64 + new_gid: u32,
     65 + ) -> Self {
     66 + Self {
     67 + pid,
     68 + _padding: 0,
     69 + binprm_inode,
     70 + old_uid,
     71 + old_gid,
     72 + new_uid,
     73 + new_gid,
     74 + }
     75 + }
     76 +}
     77 + 
     78 +impl Alert for TaskFixSetuid {}
     79 + 
     80 +#[repr(C)]
     81 +#[derive(Copy, Clone)]
     82 +pub struct SocketBind {
     83 + pub pid: u32,
     84 + _padding1: u32,
     85 + pub binprm_inode: u64,
     86 + pub port: u16,
     87 + _padding2: [u16; 3],
     88 +}
     89 + 
     90 +impl SocketBind {
     91 + pub fn new(pid: u32, binprm_inode: u64, port: u16) -> Self {
     92 + Self {
     93 + pid,
     94 + _padding1: 0,
     95 + binprm_inode,
     96 + port,
     97 + _padding2: [0; 3],
     98 + }
     99 + }
     100 +}
     101 + 
     102 +impl Alert for SocketBind {}
     103 + 
     104 +#[repr(C)]
     105 +#[derive(Copy, Clone)]
     106 +pub struct SocketConnect {
     107 + pub pid: u32,
     108 + _padding1: u32,
     109 + pub binprm_inode: u64,
     110 + pub addr_v4: u32,
     111 + _padding2: u32,
     112 + pub addr_v6: [u8; 16],
     113 +}
     114 + 
     115 +impl SocketConnect {
     116 + pub fn new_ipv4(pid: u32, binprm_inode: u64, addr_v4: u32) -> Self {
     117 + Self {
     118 + pid,
     119 + _padding1: 0,
     120 + binprm_inode,
     121 + addr_v4,
     122 + _padding2: 0,
     123 + addr_v6: [0; 16],
     124 + }
     125 + }
     126 + 
     127 + pub fn new_ipv6(pid: u32, binprm_inode: u64, addr_v6: [u8; 16]) -> Self {
     128 + Self {
     129 + pid,
     130 + _padding1: 0,
     131 + binprm_inode,
     132 + addr_v4: 0,
     133 + _padding2: 0,
     134 + addr_v6,
     135 + }
     136 + }
     137 +}
     138 + 
     139 +impl Alert for SocketConnect {}
     140 + 
     141 +#[cfg(feature = "user")]
     142 +pub mod user {
     143 + use super::*;
     144 + 
     145 + use aya::Pod;
     146 + 
     147 + unsafe impl Pod for BprmCheckSecurity {}
     148 + unsafe impl Pod for FileOpen {}
     149 + unsafe impl Pod for TaskFixSetuid {}
     150 + unsafe impl Pod for SocketBind {}
     151 + unsafe impl Pod for SocketConnect {}
     152 +}
     153 + 
  • ■ ■ ■ ■ ■
    guardity-common/src/lib.rs
    1 1  #![cfg_attr(not(feature = "user"), no_std)]
    2 2   
    3  -#[cfg(feature = "user")]
    4  -use std::net::{Ipv4Addr, Ipv6Addr};
    5  - 
    6  -#[cfg(feature = "user")]
    7  -use serde::Serialize;
     3 +pub mod alerts;
    8 4   
    9 5  pub const MAX_PATHS: usize = 4;
    10 6  pub const MAX_PORTS: usize = 1;
    11 7  pub const MAX_IPV4ADDRS: usize = 1;
    12 8  pub const MAX_IPV6ADDRS: usize = 1;
    13 9   
    14  -pub trait Alert {}
    15  - 
    16  -#[repr(C)]
    17  -#[cfg_attr(feature = "user", derive(Debug, serde::Serialize, serde::Deserialize))]
    18  -#[derive(Copy, Clone)]
    19  -pub struct AlertBprmCheckSecurity {
    20  - pub pid: u32,
    21  - #[cfg_attr(feature = "user", serde(skip))]
    22  - _padding: u32,
    23  - pub binprm_inode: u64,
    24  -}
    25  - 
    26  -impl AlertBprmCheckSecurity {
    27  - pub fn new(pid: u32, binprm_inode: u64) -> Self {
    28  - Self {
    29  - pid,
    30  - _padding: 0,
    31  - binprm_inode,
    32  - }
    33  - }
    34  -}
    35  - 
    36  -impl Alert for AlertBprmCheckSecurity {}
    37  - 
    38  -#[repr(C)]
    39  -#[cfg_attr(feature = "user", derive(Debug, serde::Serialize, serde::Deserialize))]
    40  -#[derive(Copy, Clone)]
    41  -pub struct AlertFileOpen {
    42  - pub pid: u32,
    43  - #[cfg_attr(feature = "user", serde(skip))]
    44  - _padding: u32,
    45  - pub binprm_inode: u64,
    46  - pub inode: u64,
    47  -}
    48  - 
    49  -impl AlertFileOpen {
    50  - pub fn new(pid: u32, binprm_inode: u64, inode: u64) -> Self {
    51  - Self {
    52  - pid,
    53  - _padding: 0,
    54  - binprm_inode,
    55  - inode,
    56  - }
    57  - }
    58  -}
    59  - 
    60  -impl Alert for AlertFileOpen {}
    61  - 
    62  -#[repr(C)]
    63  -#[cfg_attr(feature = "user", derive(Debug, serde::Serialize, serde::Deserialize))]
    64  -#[derive(Copy, Clone)]
    65  -pub struct AlertSetuid {
    66  - pub pid: u32,
    67  - #[cfg_attr(feature = "user", serde(skip))]
    68  - _padding: u32,
    69  - pub binprm_inode: u64,
    70  - pub old_uid: u32,
    71  - pub old_gid: u32,
    72  - pub new_uid: u32,
    73  - pub new_gid: u32,
    74  -}
    75  - 
    76  -impl AlertSetuid {
    77  - pub fn new(
    78  - pid: u32,
    79  - binprm_inode: u64,
    80  - old_uid: u32,
    81  - old_gid: u32,
    82  - new_uid: u32,
    83  - new_gid: u32,
    84  - ) -> Self {
    85  - Self {
    86  - pid,
    87  - _padding: 0,
    88  - binprm_inode,
    89  - old_uid,
    90  - old_gid,
    91  - new_uid,
    92  - new_gid,
    93  - }
    94  - }
    95  -}
    96  - 
    97  -impl Alert for AlertSetuid {}
    98  - 
    99  -#[repr(C)]
    100  -#[cfg_attr(feature = "user", derive(Debug, serde::Serialize, serde::Deserialize))]
    101  -#[derive(Copy, Clone)]
    102  -pub struct AlertSocketBind {
    103  - pub pid: u32,
    104  - #[cfg_attr(feature = "user", serde(skip))]
    105  - _padding1: u32,
    106  - pub binprm_inode: u64,
    107  - pub port: u16,
    108  - #[cfg_attr(feature = "user", serde(skip))]
    109  - _padding2: [u16; 3],
    110  -}
    111  - 
    112  -impl AlertSocketBind {
    113  - pub fn new(pid: u32, binprm_inode: u64, port: u16) -> Self {
    114  - Self {
    115  - pid,
    116  - _padding1: 0,
    117  - binprm_inode,
    118  - port,
    119  - _padding2: [0; 3],
    120  - }
    121  - }
    122  -}
    123  - 
    124  -impl Alert for AlertSocketBind {}
    125  - 
    126  -#[cfg(feature = "user")]
    127  -fn serialize_ipv4<S>(addr: &u32, s: S) -> Result<S::Ok, S::Error>
    128  -where
    129  - S: serde::Serializer,
    130  -{
    131  - Ipv4Addr::from(*addr).serialize(s)
    132  -}
    133  - 
    134  -#[cfg(feature = "user")]
    135  -fn serialize_ipv6<S>(addr: &[u8; 16], s: S) -> Result<S::Ok, S::Error>
    136  -where
    137  - S: serde::Serializer,
    138  -{
    139  - Ipv6Addr::from(addr.to_owned()).serialize(s)
    140  -}
    141  - 
    142  -#[repr(C)]
    143  -#[cfg_attr(feature = "user", derive(Debug, serde::Serialize, serde::Deserialize))]
    144  -#[derive(Copy, Clone)]
    145  -pub struct AlertSocketConnect {
    146  - pub pid: u32,
    147  - #[cfg_attr(feature = "user", serde(skip))]
    148  - _padding1: u32,
    149  - pub binprm_inode: u64,
    150  - #[cfg_attr(feature = "user", serde(serialize_with = "serialize_ipv4"))]
    151  - pub addr_v4: u32,
    152  - #[cfg_attr(feature = "user", serde(skip))]
    153  - _padding2: u32,
    154  - #[cfg_attr(feature = "user", serde(serialize_with = "serialize_ipv6"))]
    155  - pub addr_v6: [u8; 16],
    156  -}
    157  - 
    158  -impl AlertSocketConnect {
    159  - pub fn new_ipv4(pid: u32, binprm_inode: u64, addr_v4: u32) -> Self {
    160  - Self {
    161  - pid,
    162  - _padding1: 0,
    163  - binprm_inode,
    164  - addr_v4,
    165  - _padding2: 0,
    166  - addr_v6: [0; 16],
    167  - }
    168  - }
    169  - 
    170  - pub fn new_ipv6(pid: u32, binprm_inode: u64, addr_v6: [u8; 16]) -> Self {
    171  - Self {
    172  - pid,
    173  - _padding1: 0,
    174  - binprm_inode,
    175  - addr_v4: 0,
    176  - _padding2: 0,
    177  - addr_v6,
    178  - }
    179  - }
    180  -}
    181  - 
    182  -impl Alert for AlertSocketConnect {}
    183  - 
    184 10  #[repr(C)]
    185 11  #[derive(Copy, Clone)]
    186 12  pub struct Paths {
    skipped 93 lines
    280 106   
    281 107   use aya::Pod;
    282 108   
    283  - unsafe impl Pod for AlertFileOpen {}
    284  - unsafe impl Pod for AlertSetuid {}
    285 109   unsafe impl Pod for Paths {}
    286 110   unsafe impl Pod for Ports {}
    287 111   unsafe impl Pod for Ipv4Addrs {}
    skipped 3 lines
  • ■ ■ ■ ■ ■ ■
    guardity-ebpf/src/bprm_check_security.rs
    1 1  use aya_bpf::{cty::c_long, programs::LsmContext, BpfContext};
    2  -use guardity_common::AlertBprmCheckSecurity;
     2 +use guardity_common::alerts;
    3 3   
    4 4  use crate::{binprm::current_binprm_inode, maps::ALERT_BPRM_CHECK_SECURITY, vmlinux::linux_binprm};
    5 5   
    skipped 6 lines
    12 12   if argc < 1 {
    13 13   ALERT_BPRM_CHECK_SECURITY.output(
    14 14   &ctx,
    15  - &AlertBprmCheckSecurity::new(ctx.pid() as u32, old_binprm_inode),
     15 + &alerts::BprmCheckSecurity::new(ctx.pid() as u32, old_binprm_inode),
    16 16   0,
    17 17   );
    18 18   return Ok(-1);
    skipped 5 lines
  • ■ ■ ■ ■ ■ ■
    guardity-ebpf/src/file_open.rs
    1 1  use aya_bpf::{maps::HashMap, programs::LsmContext, BpfContext};
    2  -use guardity_common::{AlertFileOpen, Paths, MAX_PATHS};
     2 +use guardity_common::{alerts, Paths, MAX_PATHS};
    3 3   
    4 4  use crate::{
    5 5   binprm::current_binprm_inode,
    skipped 69 lines
    75 75   match check_conditions(map, file, inode, binprm_inode, mode) {
    76 76   Action::Allow => Action::Allow,
    77 77   Action::Deny => {
    78  - ALERT_FILE_OPEN.output(ctx, &AlertFileOpen::new(ctx.pid(), binprm_inode, inode), 0);
     78 + ALERT_FILE_OPEN.output(ctx, &alerts::FileOpen::new(ctx.pid(), binprm_inode, inode), 0);
    79 79   Action::Deny
    80 80   }
    81 81   }
    skipped 81 lines
  • ■ ■ ■ ■ ■ ■
    guardity-ebpf/src/maps.rs
    skipped 1 lines
    2 2   macros::map,
    3 3   maps::{HashMap, PerfEventArray},
    4 4  };
    5  -use guardity_common::{
    6  - AlertBprmCheckSecurity, AlertFileOpen, AlertSetuid, AlertSocketBind, AlertSocketConnect,
    7  - Ipv4Addrs, Ipv6Addrs, Paths, Ports,
    8  -};
     5 +use guardity_common::{alerts, Ipv4Addrs, Ipv6Addrs, Paths, Ports};
    9 6   
    10 7  #[map]
    11  -pub static ALERT_BPRM_CHECK_SECURITY: PerfEventArray<AlertBprmCheckSecurity> =
     8 +pub static ALERT_BPRM_CHECK_SECURITY: PerfEventArray<alerts::BprmCheckSecurity> =
    12 9   PerfEventArray::pinned(1024, 0);
    13 10   
    14 11  /// Map of allowed file open paths for each binary.
    skipped 6 lines
    21 18   
    22 19  /// Map of alerts for `file_open` LSM hook inspection.
    23 20  #[map]
    24  -pub static ALERT_FILE_OPEN: PerfEventArray<AlertFileOpen> = PerfEventArray::pinned(1024, 0);
     21 +pub static ALERT_FILE_OPEN: PerfEventArray<alerts::FileOpen> = PerfEventArray::pinned(1024, 0);
    25 22   
    26 23  /// Map indicating which binaries are allowed to use `setuid`.
    27 24  #[map]
    skipped 5 lines
    33 30   
    34 31  /// Map of alerts for `setuid` LSM hook inspection.
    35 32  #[map]
    36  -pub static ALERT_SETUID: PerfEventArray<AlertSetuid> = PerfEventArray::pinned(1024, 0);
     33 +pub static ALERT_SETUID: PerfEventArray<alerts::TaskFixSetuid> = PerfEventArray::pinned(1024, 0);
    37 34   
    38 35  /// Map of allowed socket bind ports for each binary.
    39 36  #[map]
    skipped 5 lines
    45 42   
    46 43  /// Map of alerts for `socket_bind` LSM hook inspection.
    47 44  #[map]
    48  -pub static ALERT_SOCKET_BIND: PerfEventArray<AlertSocketBind> = PerfEventArray::pinned(1024, 0);
     45 +pub static ALERT_SOCKET_BIND: PerfEventArray<alerts::SocketBind> = PerfEventArray::pinned(1024, 0);
    49 46   
    50 47  /// Map of allowed socket connect IPv4 addresses for each binary.
    51 48  #[map]
    skipped 13 lines
    65 62   
    66 63  /// Map of alerts for `socket_connect` LSM hook inspection.
    67 64  #[map]
    68  -pub static ALERT_SOCKET_CONNECT: PerfEventArray<AlertSocketConnect> =
     65 +pub static ALERT_SOCKET_CONNECT: PerfEventArray<alerts::SocketConnect> =
    69 66   PerfEventArray::pinned(1024, 0);
    70 67   
  • ■ ■ ■ ■ ■
    guardity-ebpf/src/setuid.rs
    1 1  use aya_bpf::{cty::c_long, programs::LsmContext, BpfContext};
    2  -use guardity_common::AlertSetuid;
     2 +use guardity_common::alerts;
    3 3   
    4 4  use crate::{
    5 5   binprm::current_binprm_inode,
    6 6   consts::INODE_WILDCARD,
    7  - vmlinux::cred, maps::{ALLOWED_SETUID, DENIED_SETUID, ALERT_SETUID},
     7 + maps::{ALERT_SETUID, ALLOWED_SETUID, DENIED_SETUID},
     8 + vmlinux::cred,
    8 9  };
    9 10   
    10 11  /// Inspects the context of `task_fix_setuid` LSM hook and decides whether to
    skipped 30 lines
    41 42   if unsafe { DENIED_SETUID.get(&binprm_inode).is_some() } {
    42 43   ALERT_SETUID.output(
    43 44   &ctx,
    44  - &AlertSetuid::new(ctx.pid(), binprm_inode, old_uid, old_gid, new_uid, new_gid),
     45 + &alerts::TaskFixSetuid::new(
     46 + ctx.pid(),
     47 + binprm_inode,
     48 + old_uid,
     49 + old_gid,
     50 + new_uid,
     51 + new_gid,
     52 + ),
    45 53   0,
    46 54   );
    47 55   return Ok(-1);
    skipped 7 lines
    55 63   }
    56 64   ALERT_SETUID.output(
    57 65   &ctx,
    58  - &AlertSetuid::new(ctx.pid(), binprm_inode, old_uid, old_gid, new_uid, new_gid),
     66 + &alerts::TaskFixSetuid::new(
     67 + ctx.pid(),
     68 + binprm_inode,
     69 + old_uid,
     70 + old_gid,
     71 + new_uid,
     72 + new_gid,
     73 + ),
    59 74   0,
    60 75   );
    61 76   return Ok(-1);
    skipped 5 lines
  • ■ ■ ■ ■ ■ ■
    guardity-ebpf/src/socket_bind.rs
    1 1  use core::cmp;
    2 2   
    3 3  use aya_bpf::{cty::c_long, programs::LsmContext, BpfContext};
    4  -use guardity_common::{AlertSocketBind, MAX_PORTS};
     4 +use guardity_common::{alerts, MAX_PORTS};
    5 5   
    6 6  use crate::{
    7 7   binprm::current_binprm_inode,
    skipped 45 lines
    53 53   if ports.all {
    54 54   ALERT_SOCKET_BIND.output(
    55 55   &ctx,
    56  - &AlertSocketBind::new(ctx.pid(), binprm_inode, port),
     56 + &alerts::SocketBind::new(ctx.pid(), binprm_inode, port),
    57 57   0,
    58 58   );
    59 59   return Ok(-1);
    skipped 2 lines
    62 62   if ports.ports[..len].contains(&port) {
    63 63   ALERT_SOCKET_BIND.output(
    64 64   &ctx,
    65  - &AlertSocketBind::new(ctx.pid(), binprm_inode, port),
     65 + &alerts::SocketBind::new(ctx.pid(), binprm_inode, port),
    66 66   0,
    67 67   );
    68 68   return Ok(-1);
    skipped 4 lines
    73 73   if ports.all {
    74 74   ALERT_SOCKET_BIND.output(
    75 75   &ctx,
    76  - &AlertSocketBind::new(ctx.pid(), binprm_inode, port),
     76 + &alerts::SocketBind::new(ctx.pid(), binprm_inode, port),
    77 77   0,
    78 78   );
    79 79   return Ok(-1);
    skipped 2 lines
    82 82   if ports.ports[..len].contains(&port) {
    83 83   ALERT_SOCKET_BIND.output(
    84 84   &ctx,
    85  - &AlertSocketBind::new(ctx.pid(), binprm_inode, port),
     85 + &alerts::SocketBind::new(ctx.pid(), binprm_inode, port),
    86 86   0,
    87 87   );
    88 88   return Ok(-1);
    skipped 31 lines
    120 120   
    121 121   ALERT_SOCKET_BIND.output(
    122 122   &ctx,
    123  - &AlertSocketBind::new(ctx.pid(), binprm_inode, port),
     123 + &alerts::SocketBind::new(ctx.pid(), binprm_inode, port),
    124 124   0,
    125 125   );
    126 126   return Ok(-1);
    skipped 2 lines
    129 129   if ports.ports[..len].contains(&port) {
    130 130   ALERT_SOCKET_BIND.output(
    131 131   &ctx,
    132  - &AlertSocketBind::new(ctx.pid(), binprm_inode, port),
     132 + &alerts::SocketBind::new(ctx.pid(), binprm_inode, port),
    133 133   0,
    134 134   );
    135 135   return Ok(-1);
    skipped 7 lines
  • ■ ■ ■ ■ ■ ■
    guardity-ebpf/src/socket_connect.rs
    1 1  use aya_bpf::{
    2 2   cty::c_long, helpers::bpf_probe_read_kernel, maps::HashMap, programs::LsmContext, BpfContext,
    3 3  };
    4  -use guardity_common::{AlertSocketConnect, IpAddrs, Ipv4Addrs, Ipv6Addrs};
     4 +use guardity_common::{alerts, IpAddrs, Ipv4Addrs, Ipv6Addrs};
    5 5   
    6 6  use crate::{
    7 7   binprm::current_binprm_inode,
    skipped 118 lines
    126 126   Action::Deny => {
    127 127   ALERT_SOCKET_CONNECT.output(
    128 128   ctx,
    129  - &AlertSocketConnect::new_ipv4(ctx.pid(), binprm_inode, addr),
     129 + &alerts::SocketConnect::new_ipv4(ctx.pid(), binprm_inode, addr),
    130 130   0,
    131 131   );
    132 132   Action::Deny
    skipped 14 lines
    147 147   Action::Deny => {
    148 148   ALERT_SOCKET_CONNECT.output(
    149 149   ctx,
    150  - &AlertSocketConnect::new_ipv6(ctx.pid(), binprm_inode, addr),
     150 + &alerts::SocketConnect::new_ipv6(ctx.pid(), binprm_inode, addr),
    151 151   0,
    152 152   );
    153 153   Action::Deny
    skipped 57 lines
Please wait...
Page is in error, reload to recover