■ ■ ■ ■ ■ ■
guardity-ebpf/src/socket_bind.rs
1 | | - | use core::cmp; |
2 | | - | |
3 | | - | use aya_bpf::{cty::c_long, programs::LsmContext, BpfContext}; |
| 1 | + | use aya_bpf::{programs::LsmContext, BpfContext}; |
4 | 2 | | use guardity_common::{alerts, consts::INODE_WILDCARD, policy::MAX_PORTS}; |
5 | 3 | | |
6 | 4 | | use crate::{ |
| skipped 1 lines |
8 | 6 | | consts::AF_INET, |
9 | 7 | | maps::{ALERT_SOCKET_BIND, ALLOWED_SOCKET_BIND, DENIED_SOCKET_BIND}, |
10 | 8 | | vmlinux::{sockaddr, sockaddr_in}, |
| 9 | + | Action, |
11 | 10 | | }; |
12 | 11 | | |
13 | 12 | | /// Inspects the context of `socket_bind` LSM hook and decides whether to allow |
| skipped 17 lines |
31 | 30 | | /// } |
32 | 31 | | /// ``` |
33 | 32 | | #[inline(always)] |
34 | | - | pub fn socket_bind(ctx: LsmContext) -> Result<i32, c_long> { |
| 33 | + | pub fn socket_bind(ctx: LsmContext) -> Action { |
35 | 34 | | let sockaddr: *const sockaddr = unsafe { ctx.arg(1) }; |
36 | 35 | | |
37 | 36 | | if unsafe { (*sockaddr).sa_family } != AF_INET { |
38 | | - | return Ok(0); |
| 37 | + | return Action::Allow; |
39 | 38 | | } |
40 | 39 | | |
41 | 40 | | let sockaddr_in: *const sockaddr_in = sockaddr as *const sockaddr_in; |
42 | 41 | | let port = u16::from_be(unsafe { (*sockaddr_in).sin_port }); |
43 | 42 | | |
44 | 43 | | if port == 0 { |
45 | | - | return Ok(0); |
| 44 | + | return Action::Allow; |
46 | 45 | | } |
47 | 46 | | |
48 | 47 | | let binprm_inode = current_binprm_inode(); |
49 | 48 | | |
50 | 49 | | if let Some(ports) = unsafe { ALLOWED_SOCKET_BIND.get(&INODE_WILDCARD) } { |
51 | | - | if ports.all { |
| 50 | + | if ports.all() { |
52 | 51 | | if let Some(ports) = unsafe { DENIED_SOCKET_BIND.get(&INODE_WILDCARD) } { |
53 | | - | if ports.all { |
| 52 | + | if ports.all() { |
54 | 53 | | ALERT_SOCKET_BIND.output( |
55 | 54 | | &ctx, |
56 | 55 | | &alerts::SocketBind::new(ctx.pid(), binprm_inode, port), |
57 | 56 | | 0, |
58 | 57 | | ); |
59 | | - | return Ok(-1); |
| 58 | + | return Action::Deny; |
60 | 59 | | } |
61 | | - | let len = cmp::min(ports.len, MAX_PORTS); |
62 | | - | if ports.ports[..len].contains(&port) { |
| 60 | + | if ports.ports[..MAX_PORTS - 1].contains(&port) { |
63 | 61 | | ALERT_SOCKET_BIND.output( |
64 | 62 | | &ctx, |
65 | 63 | | &alerts::SocketBind::new(ctx.pid(), binprm_inode, port), |
66 | 64 | | 0, |
67 | 65 | | ); |
68 | | - | return Ok(-1); |
| 66 | + | return Action::Deny; |
69 | 67 | | } |
70 | 68 | | } |
71 | 69 | | |
72 | 70 | | if let Some(ports) = unsafe { DENIED_SOCKET_BIND.get(&binprm_inode) } { |
73 | | - | if ports.all { |
| 71 | + | if ports.all() { |
74 | 72 | | ALERT_SOCKET_BIND.output( |
75 | 73 | | &ctx, |
76 | 74 | | &alerts::SocketBind::new(ctx.pid(), binprm_inode, port), |
77 | 75 | | 0, |
78 | 76 | | ); |
79 | | - | return Ok(-1); |
| 77 | + | return Action::Deny; |
80 | 78 | | } |
81 | | - | let len = cmp::min(ports.len, MAX_PORTS); |
82 | | - | if ports.ports[..len].contains(&port) { |
| 79 | + | if ports.ports[..MAX_PORTS - 1].contains(&port) { |
83 | 80 | | ALERT_SOCKET_BIND.output( |
84 | 81 | | &ctx, |
85 | 82 | | &alerts::SocketBind::new(ctx.pid(), binprm_inode, port), |
86 | 83 | | 0, |
87 | 84 | | ); |
88 | | - | return Ok(-1); |
| 85 | + | return Action::Deny; |
89 | 86 | | } |
90 | 87 | | } |
91 | 88 | | } else { |
92 | | - | let len = cmp::min(ports.len, MAX_PORTS); |
93 | | - | if ports.ports[..len].contains(&port) { |
94 | | - | return Ok(0); |
| 89 | + | if ports.ports[..MAX_PORTS - 1].contains(&port) { |
| 90 | + | return Action::Allow; |
95 | 91 | | } |
96 | 92 | | } |
97 | 93 | | } |
98 | 94 | | |
99 | 95 | | if let Some(ports) = unsafe { DENIED_SOCKET_BIND.get(&INODE_WILDCARD) } { |
100 | | - | if ports.all { |
| 96 | + | if ports.all() { |
101 | 97 | | if let Some(ports) = unsafe { ALLOWED_SOCKET_BIND.get(&INODE_WILDCARD) } { |
102 | | - | if ports.all { |
103 | | - | return Ok(0); |
| 98 | + | if ports.all() { |
| 99 | + | return Action::Allow; |
104 | 100 | | } |
105 | | - | let len = cmp::min(ports.len, MAX_PORTS); |
106 | | - | if ports.ports[..len].contains(&port) { |
107 | | - | return Ok(0); |
| 101 | + | if ports.ports[..MAX_PORTS - 1].contains(&port) { |
| 102 | + | return Action::Allow; |
108 | 103 | | } |
109 | 104 | | } |
110 | 105 | | |
111 | 106 | | if let Some(ports) = unsafe { ALLOWED_SOCKET_BIND.get(&binprm_inode) } { |
112 | | - | if ports.all { |
113 | | - | return Ok(0); |
| 107 | + | if ports.all() { |
| 108 | + | return Action::Allow; |
114 | 109 | | } |
115 | | - | let len = cmp::min(ports.len, MAX_PORTS); |
116 | | - | if ports.ports[..len].contains(&port) { |
117 | | - | return Ok(0); |
| 110 | + | if ports.ports[..MAX_PORTS - 1].contains(&port) { |
| 111 | + | return Action::Allow; |
118 | 112 | | } |
119 | 113 | | } |
120 | 114 | | |
| skipped 2 lines |
123 | 117 | | &alerts::SocketBind::new(ctx.pid(), binprm_inode, port), |
124 | 118 | | 0, |
125 | 119 | | ); |
126 | | - | return Ok(-1); |
| 120 | + | return Action::Deny; |
127 | 121 | | } else { |
128 | | - | let len = cmp::min(ports.len, MAX_PORTS); |
129 | | - | if ports.ports[..len].contains(&port) { |
| 122 | + | if ports.ports[..MAX_PORTS - 1].contains(&port) { |
130 | 123 | | ALERT_SOCKET_BIND.output( |
131 | 124 | | &ctx, |
132 | 125 | | &alerts::SocketBind::new(ctx.pid(), binprm_inode, port), |
133 | 126 | | 0, |
134 | 127 | | ); |
135 | | - | return Ok(-1); |
| 128 | + | return Action::Deny; |
136 | 129 | | } |
137 | 130 | | } |
138 | 131 | | } |
139 | 132 | | |
140 | | - | Ok(0) |
| 133 | + | Action::Allow |
141 | 134 | | } |
142 | 135 | | |