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 -