Projects STRLCPY ebpfguard Commits 8f97c919
🤬
  • common: Store just an array in `Ipv*Addrs` structs

    Addresses represented by `0` or arrays with zeros are wildcard. So when the
    first element of the array is `0` or `[0u8; 16]`, we can just assume
    that we have a wildcard policy. Therefore we can get rid of the `all`
    field.
    
    `len` field would be useful to reduce the number of iterations when
    matching, but it trips the verifier.
  • Loading...
  • Michal Rostecki committed with vadorovsky 1 year ago
    8f97c919
    1 parent dc6c68d1
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    guardctl/src/policy/socket_connect.rs
    skipped 44 lines
    45 45   for subject in subjects {
    46 46   let mut allowed = match allowed_socket_connect_v4.get(&subject, 0) {
    47 47   Ok(allowed) => {
    48  - if allowed.all {
     48 + if allowed.all() {
    49 49   Addresses::All
    50 50   } else {
    51 51   Addresses::Addresses(
    skipped 11 lines
    63 63   if let Addresses::Addresses(addrs) = &mut allowed {
    64 64   match allowed_socket_connect_v6.get(&subject, 0) {
    65 65   Ok(allowed) => {
    66  - if allowed.all {
     66 + if allowed.all() {
    67 67   anyhow::bail!("Inconsistent policies: allowed all IPv6 addresses, but specified IPv4 addresses")
    68 68   } else {
    69 69   addrs.extend(allowed.addrs.iter().map(|a| IpAddr::V6(Ipv6Addr::from(*a))));
    skipped 6 lines
    76 76   
    77 77   let mut denied = match denied_socket_connect_v4.get(&subject, 0) {
    78 78   Ok(denied) => {
    79  - if denied.all {
     79 + if denied.all() {
    80 80   Addresses::All
    81 81   } else {
    82 82   Addresses::Addresses(
    skipped 11 lines
    94 94   if let Addresses::Addresses(addrs) = &mut denied {
    95 95   match denied_socket_connect_v6.get(&subject, 0) {
    96 96   Ok(denied) => {
    97  - if denied.all {
     97 + if denied.all() {
    98 98   anyhow::bail!("Inconsistent policies: denied all IPv6 addresses, but specified IPv4 addresses")
    99 99   } else {
    100 100   addrs.extend(denied.addrs.iter().map(|a| IpAddr::V6(Ipv6Addr::from(*a))));
    skipped 39 lines
  • ■ ■ ■ ■ ■ ■
    guardity/src/policy/mod.rs
    skipped 124 lines
    125 125   guardity_common::Ipv6Addrs::new_all(),
    126 126   ),
    127 127   Addresses::Addresses(addrs) => {
    128  - let mut ebpf_addrs_v4_len = 0;
    129 128   let mut ebpf_addrs_v4 = [0; guardity_common::MAX_IPV4ADDRS];
    130  - let mut ebpf_addrs_v6_len = 0;
    131 129   let mut ebpf_addrs_v6 = [[0u8; 16]; guardity_common::MAX_IPV6ADDRS];
    132 130   let mut i_v4 = 0;
    133 131   let mut i_v6 = 0;
    skipped 2 lines
    136 134   IpAddr::V4(ipv4) => {
    137 135   ebpf_addrs_v4[i_v4] = (*ipv4).into();
    138 136   i_v4 += 1;
    139  - ebpf_addrs_v4_len += 1;
    140 137   }
    141 138   IpAddr::V6(ipv6) => {
    142 139   ebpf_addrs_v6[i_v6] = ipv6.octets();
    143 140   i_v6 += 1;
    144  - ebpf_addrs_v6_len += 1;
    145 141   }
    146 142   }
    147 143   }
    148 144   (
    149  - guardity_common::Ipv4Addrs::new(ebpf_addrs_v4_len, ebpf_addrs_v4),
    150  - guardity_common::Ipv6Addrs::new(ebpf_addrs_v6_len, ebpf_addrs_v6),
     145 + guardity_common::Ipv4Addrs::new(ebpf_addrs_v4),
     146 + guardity_common::Ipv6Addrs::new(ebpf_addrs_v6),
    151 147   )
    152 148   }
    153 149   }
    skipped 214 lines
  • ■ ■ ■ ■ ■ ■
    guardity-common/src/lib.rs
    skipped 193 lines
    194 194  #[repr(C)]
    195 195  #[derive(Copy, Clone)]
    196 196  pub struct Ipv4Addrs {
    197  - pub all: bool,
    198  - pub _padding1: [u8; 7],
    199  - pub len: usize,
    200 197   pub addrs: [u32; MAX_IPV4ADDRS],
    201  - pub _padding2: [u32; MAX_IPV4ADDRS],
    202 198  }
    203 199   
    204 200  impl Ipv4Addrs {
    205  - pub fn new(len: usize, addrs: [u32; MAX_IPV4ADDRS]) -> Self {
    206  - Self {
    207  - all: false,
    208  - _padding1: [0; 7],
    209  - len,
    210  - addrs,
    211  - _padding2: [0; MAX_IPV4ADDRS],
    212  - }
     201 + pub fn new(addrs: [u32; MAX_IPV4ADDRS]) -> Self {
     202 + Self { addrs }
    213 203   }
    214 204   
    215 205   pub fn new_all() -> Self {
    216 206   Self {
    217  - all: true,
    218  - _padding1: [0; 7],
    219  - len: 0,
    220 207   addrs: [0; MAX_IPV4ADDRS],
    221  - _padding2: [0; MAX_IPV4ADDRS],
    222 208   }
    223 209   }
     210 + 
     211 + #[inline(always)]
     212 + pub fn all(&self) -> bool {
     213 + self.addrs[0] == 0
     214 + }
    224 215  }
    225 216   
    226 217  #[repr(C)]
    227 218  #[derive(Copy, Clone)]
    228 219  pub struct Ipv6Addrs {
    229  - pub all: bool,
    230  - pub _padding1: [u8; 7],
    231  - pub len: usize,
    232 220   pub addrs: [[u8; 16]; MAX_IPV4ADDRS],
    233 221  }
    234 222   
    235 223  impl Ipv6Addrs {
    236  - pub fn new(len: usize, addrs: [[u8; 16]; MAX_IPV4ADDRS]) -> Self {
    237  - Self {
    238  - all: false,
    239  - _padding1: [0; 7],
    240  - len,
    241  - addrs,
    242  - }
     224 + pub fn new(addrs: [[u8; 16]; MAX_IPV4ADDRS]) -> Self {
     225 + Self { addrs }
    243 226   }
    244 227   
    245 228   pub fn new_all() -> Self {
    246 229   Self {
    247  - all: true,
    248  - _padding1: [0; 7],
    249  - len: 0,
    250 230   addrs: [[0; 16]; MAX_IPV4ADDRS],
    251 231   }
     232 + }
     233 + 
     234 + #[inline(always)]
     235 + pub fn all(&self) -> bool {
     236 + self.addrs[0] == [0; 16]
    252 237   }
    253 238  }
    254 239   
    skipped 14 lines
  • ■ ■ ■ ■ ■ ■
    guardity-ebpf/src/socket_connect.rs
    1  -use core::cmp;
    2  - 
    3 1  use aya_bpf::{cty::c_long, helpers::bpf_probe_read_kernel, programs::LsmContext, BpfContext};
    4 2  use guardity_common::{AlertSocketConnect, MAX_IPV4ADDRS, MAX_IPV6ADDRS};
    5 3   
    skipped 7 lines
    13 11   vmlinux::{sockaddr, sockaddr_in, sockaddr_in6},
    14 12  };
    15 13   
     14 +/// Inspects the context of `socket_connect` LSM hook and decides whether to
     15 +/// allow or deny the operation based on the state of the
     16 +/// `ALLOWED_SOCKET_CONNECT_V4`/`ALLOWED_SOCKET_CONNECT_V6` and
     17 +/// `DENIED_SOCKET_CONNECT_V4`/`DENIED_SOCKET_CONNECT_V6` maps.
     18 +pub fn socket_connect(ctx: LsmContext) -> Result<i32, c_long> {
     19 + let sockaddr: *const sockaddr = unsafe { ctx.arg(1) };
     20 + let sa_family = unsafe { (*sockaddr).sa_family };
     21 + 
     22 + match sa_family {
     23 + AF_INET => socket_connect_v4(ctx, sockaddr),
     24 + AF_INET6 => socket_connect_v6(ctx, sockaddr),
     25 + _ => Ok(0),
     26 + }
     27 +}
     28 + 
    16 29  #[inline(always)]
    17 30  fn socket_connect_v4(ctx: LsmContext, sockaddr: *const sockaddr) -> Result<i32, c_long> {
    18 31   let sockaddr_in: *const sockaddr_in = sockaddr as *const sockaddr_in;
    skipped 2 lines
    21 34   let binprm_inode = current_binprm_inode();
    22 35   
    23 36   if let Some(addrs) = unsafe { ALLOWED_SOCKET_CONNECT_V4.get(&INODE_WILDCARD) } {
    24  - if addrs.all {
     37 + if addrs.all() {
    25 38   if let Some(addrs) = unsafe { DENIED_SOCKET_CONNECT_V4.get(&INODE_WILDCARD) } {
    26  - if addrs.all {
     39 + if addrs.all() {
    27 40   ALERT_SOCKET_CONNECT.output(
    28 41   &ctx,
    29 42   &AlertSocketConnect::new_ipv4(ctx.pid(), binprm_inode, addr),
    skipped 1 lines
    31 44   );
    32 45   return Ok(-1);
    33 46   }
    34  - let len = cmp::min(addrs.len, MAX_IPV4ADDRS);
    35  - if addrs.addrs[..len].contains(&addr) {
     47 + if addrs.addrs[..MAX_IPV4ADDRS].contains(&addr) {
    36 48   ALERT_SOCKET_CONNECT.output(
    37 49   &ctx,
    38 50   &AlertSocketConnect::new_ipv4(ctx.pid(), binprm_inode, addr),
    skipped 4 lines
    43 55   }
    44 56   
    45 57   if let Some(addrs) = unsafe { DENIED_SOCKET_CONNECT_V4.get(&binprm_inode) } {
    46  - if addrs.all {
     58 + if addrs.all() {
    47 59   ALERT_SOCKET_CONNECT.output(
    48 60   &ctx,
    49 61   &AlertSocketConnect::new_ipv4(ctx.pid(), binprm_inode, addr),
    skipped 1 lines
    51 63   );
    52 64   return Ok(-1);
    53 65   }
    54  - let len = cmp::min(addrs.len, MAX_IPV4ADDRS);
    55  - if addrs.addrs[..len].contains(&addr) {
     66 + if addrs.addrs[..MAX_IPV4ADDRS].contains(&addr) {
    56 67   ALERT_SOCKET_CONNECT.output(
    57 68   &ctx,
    58 69   &AlertSocketConnect::new_ipv4(ctx.pid(), binprm_inode, addr),
    skipped 3 lines
    62 73   }
    63 74   }
    64 75   } else {
    65  - let len = cmp::min(addrs.len, MAX_IPV4ADDRS);
    66  - if addrs.addrs[..len].contains(&addr) {
     76 + if addrs.addrs[..MAX_IPV4ADDRS].contains(&addr) {
    67 77   return Ok(0);
    68 78   }
    69 79   }
    70 80   }
    71 81   
    72 82   if let Some(addrs) = unsafe { DENIED_SOCKET_CONNECT_V4.get(&INODE_WILDCARD) } {
    73  - if addrs.all {
     83 + if addrs.all() {
    74 84   if let Some(addrs) = unsafe { ALLOWED_SOCKET_CONNECT_V4.get(&INODE_WILDCARD) } {
    75  - if addrs.all {
     85 + if addrs.all() {
    76 86   return Ok(0);
    77 87   }
    78  - let len = cmp::min(addrs.len, MAX_IPV4ADDRS);
    79  - if addrs.addrs[..len].contains(&addr) {
     88 + if addrs.addrs[..MAX_IPV4ADDRS].contains(&addr) {
    80 89   return Ok(0);
    81 90   }
    82 91   }
    83 92   
    84 93   if let Some(addrs) = unsafe { ALLOWED_SOCKET_CONNECT_V4.get(&binprm_inode) } {
    85  - if addrs.all {
     94 + if addrs.all() {
    86 95   return Ok(0);
    87 96   }
    88  - let len = cmp::min(addrs.len, MAX_IPV4ADDRS);
    89  - if addrs.addrs[..len].contains(&addr) {
     97 + if addrs.addrs[..MAX_IPV4ADDRS].contains(&addr) {
    90 98   return Ok(0);
    91 99   }
    92 100   }
    skipped 5 lines
    98 106   );
    99 107   return Ok(-1);
    100 108   } else {
    101  - let len = cmp::min(addrs.len, MAX_IPV4ADDRS);
    102  - if addrs.addrs[..len].contains(&addr) {
     109 + if addrs.addrs[..MAX_IPV4ADDRS].contains(&addr) {
    103 110   ALERT_SOCKET_CONNECT.output(
    104 111   &ctx,
    105 112   &AlertSocketConnect::new_ipv4(ctx.pid(), binprm_inode, addr),
    skipped 17 lines
    123 130   let binprm_inode = current_binprm_inode();
    124 131   
    125 132   if let Some(addrs) = unsafe { ALLOWED_SOCKET_CONNECT_V6.get(&INODE_WILDCARD) } {
    126  - if addrs.all {
     133 + if addrs.all() {
    127 134   if let Some(addrs) = unsafe { DENIED_SOCKET_CONNECT_V6.get(&INODE_WILDCARD) } {
    128  - if addrs.all {
     135 + if addrs.all() {
    129 136   ALERT_SOCKET_CONNECT.output(
    130 137   &ctx,
    131 138   &AlertSocketConnect::new_ipv6(ctx.pid(), binprm_inode, addr),
    skipped 1 lines
    133 140   );
    134 141   return Ok(-1);
    135 142   }
    136  - let len = cmp::min(addrs.len, MAX_IPV6ADDRS);
    137  - if addrs.addrs[..len].contains(&addr) {
     143 + if addrs.addrs[..MAX_IPV6ADDRS].contains(&addr) {
    138 144   ALERT_SOCKET_CONNECT.output(
    139 145   &ctx,
    140 146   &AlertSocketConnect::new_ipv6(ctx.pid(), binprm_inode, addr),
    skipped 4 lines
    145 151   }
    146 152   
    147 153   if let Some(addrs) = unsafe { DENIED_SOCKET_CONNECT_V6.get(&binprm_inode) } {
    148  - if addrs.all {
     154 + if addrs.all() {
    149 155   ALERT_SOCKET_CONNECT.output(
    150 156   &ctx,
    151 157   &AlertSocketConnect::new_ipv6(ctx.pid(), binprm_inode, addr),
    skipped 1 lines
    153 159   );
    154 160   return Ok(-1);
    155 161   }
    156  - let len = cmp::min(addrs.len, MAX_IPV6ADDRS);
    157  - if addrs.addrs[..len].contains(&addr) {
     162 + if addrs.addrs[..MAX_IPV6ADDRS].contains(&addr) {
    158 163   ALERT_SOCKET_CONNECT.output(
    159 164   &ctx,
    160 165   &AlertSocketConnect::new_ipv6(ctx.pid(), binprm_inode, addr),
    skipped 3 lines
    164 169   }
    165 170   }
    166 171   } else {
    167  - let len = cmp::min(addrs.len, MAX_IPV6ADDRS);
    168  - if addrs.addrs[..len].contains(&addr) {
     172 + if addrs.addrs[..MAX_IPV6ADDRS].contains(&addr) {
    169 173   return Ok(0);
    170 174   }
    171 175   }
    172 176   }
    173 177   
    174 178   if let Some(addrs) = unsafe { DENIED_SOCKET_CONNECT_V6.get(&INODE_WILDCARD) } {
    175  - if addrs.all {
     179 + if addrs.all() {
    176 180   if let Some(addrs) = unsafe { ALLOWED_SOCKET_CONNECT_V6.get(&INODE_WILDCARD) } {
    177  - if addrs.all {
     181 + if addrs.all() {
    178 182   return Ok(0);
    179 183   }
    180  - let len = cmp::min(addrs.len, MAX_IPV6ADDRS);
    181  - if addrs.addrs[..len].contains(&addr) {
     184 + if addrs.addrs[..MAX_IPV6ADDRS].contains(&addr) {
    182 185   return Ok(0);
    183 186   }
    184 187   }
    185 188   
    186 189   if let Some(addrs) = unsafe { ALLOWED_SOCKET_CONNECT_V6.get(&binprm_inode) } {
    187  - if addrs.all {
     190 + if addrs.all() {
    188 191   return Ok(0);
    189 192   }
    190  - let len = cmp::min(addrs.len, MAX_IPV6ADDRS);
    191  - if addrs.addrs[..len].contains(&addr) {
     193 + if addrs.addrs[..MAX_IPV6ADDRS].contains(&addr) {
    192 194   return Ok(0);
    193 195   }
    194 196   }
    skipped 5 lines
    200 202   );
    201 203   return Ok(-1);
    202 204   } else {
    203  - let len = cmp::min(addrs.len, MAX_IPV6ADDRS);
    204  - if addrs.addrs[..len].contains(&addr) {
     205 + if addrs.addrs[..MAX_IPV6ADDRS].contains(&addr) {
    205 206   ALERT_SOCKET_CONNECT.output(
    206 207   &ctx,
    207 208   &AlertSocketConnect::new_ipv6(ctx.pid(), binprm_inode, addr),
    skipped 7 lines
    215 216   Ok(0)
    216 217  }
    217 218   
    218  -/// Inspects the context of `socket_connect` LSM hook and decides whether to
    219  -/// allow or deny the operation based on the state of the
    220  -/// `ALLOWED_SOCKET_CONNECT_V4`/`ALLOWED_SOCKET_CONNECT_V6` and
    221  -/// `DENIED_SOCKET_CONNECT_V4`/`DENIED_SOCKET_CONNECT_V6` maps.
    222  -pub fn socket_connect(ctx: LsmContext) -> Result<i32, c_long> {
    223  - let sockaddr: *const sockaddr = unsafe { ctx.arg(1) };
    224  - let sa_family = unsafe { (*sockaddr).sa_family };
    225  - 
    226  - match sa_family {
    227  - AF_INET => socket_connect_v4(ctx, sockaddr),
    228  - AF_INET6 => socket_connect_v6(ctx, sockaddr),
    229  - _ => Ok(0),
    230  - }
    231  -}
    232  - 
Please wait...
Page is in error, reload to recover