Skip to content
This repository was archived by the owner on Jul 19, 2024. It is now read-only.

Commit 85864dd

Browse files
Andreagit97poiana
authored andcommitted
new(modern_bpf): add capset syscall
Signed-off-by: Andrea Terzolo <[email protected]>
1 parent 23274b2 commit 85864dd

File tree

6 files changed

+440
-0
lines changed

6 files changed

+440
-0
lines changed

driver/modern_bpf/definitions/events_dimensions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,7 @@
5959
#define SECCOMP_E_SIZE HEADER_LEN + sizeof(uint64_t) + PARAM_LEN
6060
#define SECCOMP_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN
6161
#define PTRACE_E_SIZE HEADER_LEN + sizeof(int64_t) + sizeof(uint16_t) + PARAM_LEN * 2
62+
#define CAPSET_E_SIZE HEADER_LEN
63+
#define CAPSET_X_SIZE HEADER_LEN + sizeof(int64_t) + sizeof(uint64_t) * 3 + PARAM_LEN * 4
6264

6365
#endif /* __EVENT_DIMENSIONS_H__ */

driver/modern_bpf/helpers/extract/extract_from_kernel.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@
1111
#include <helpers/base/read_from_task.h>
1212
#include <driver/ppm_flag_helpers.h>
1313

14+
/* This enum should simplify the capabilities extraction. */
15+
enum capability_type
16+
{
17+
CAP_INHERITABLE = 0,
18+
CAP_PERMITTED = 1,
19+
CAP_EFFECTIVE = 2,
20+
};
21+
1422
/* All the functions that are called in bpf to extract parameters
1523
* start with the `extract` prefix.
1624
*/
@@ -138,3 +146,52 @@ static __always_inline void extract__dev_and_ino_from_fd(s32 fd, dev_t *dev, u64
138146
*dev = encode_dev(*dev);
139147
BPF_CORE_READ_INTO(ino, f, f_inode, i_ino);
140148
}
149+
150+
/////////////////////////
151+
// CAPABILITIES EXTRACTION
152+
////////////////////////
153+
154+
/**
155+
* @brief Extract capabilities
156+
*
157+
* Right now we support only 3 types of capabilities:
158+
* - cap_inheritable
159+
* - cap_permitted
160+
* - cap_effective
161+
*
162+
* To extract the specific capabilities use the enum defined by us
163+
* at the beginning of this file:
164+
* - CAP_INHERITABLE
165+
* - CAP_PERMITTED
166+
* - CAP_EFFECTIVE
167+
*
168+
* @param task pointer to task struct.
169+
* @param capability_type type of capability to extract defined by us.
170+
* @return PPM encoded capability value
171+
*/
172+
static __always_inline u64 extract__capability(struct task_struct *task, enum capability_type capability_type)
173+
{
174+
kernel_cap_t cap_struct;
175+
unsigned long capability;
176+
177+
switch(capability_type)
178+
{
179+
case CAP_INHERITABLE:
180+
READ_TASK_FIELD_INTO(&cap_struct, task, cred, cap_inheritable);
181+
break;
182+
183+
case CAP_PERMITTED:
184+
READ_TASK_FIELD_INTO(&cap_struct, task, cred, cap_permitted);
185+
break;
186+
187+
case CAP_EFFECTIVE:
188+
READ_TASK_FIELD_INTO(&cap_struct, task, cred, cap_effective);
189+
break;
190+
191+
default:
192+
return 0;
193+
break;
194+
}
195+
196+
return capabilities_to_scap(((unsigned long)cap_struct.cap[1] << 32) | cap_struct.cap[0]);
197+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (C) 2022 The Falco Authors.
3+
*
4+
* This file is dual licensed under either the MIT or GPL 2. See MIT.txt
5+
* or GPL2.txt for full copies of the license.
6+
*/
7+
8+
#include <helpers/interfaces/fixed_size_event.h>
9+
10+
/*=============================== ENTER EVENT ===========================*/
11+
12+
SEC("tp_btf/sys_enter")
13+
int BPF_PROG(capset_e,
14+
struct pt_regs *regs,
15+
long id)
16+
{
17+
struct ringbuf_struct ringbuf;
18+
if(!ringbuf__reserve_space(&ringbuf, CAPSET_E_SIZE))
19+
{
20+
return 0;
21+
}
22+
23+
ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_CAPSET_E, CAPSET_E_SIZE);
24+
25+
/*=============================== COLLECT PARAMETERS ===========================*/
26+
27+
// Here we have no parameters to collect.
28+
29+
/*=============================== COLLECT PARAMETERS ===========================*/
30+
31+
ringbuf__submit_event(&ringbuf);
32+
33+
return 0;
34+
}
35+
36+
/*=============================== ENTER EVENT ===========================*/
37+
38+
/*=============================== EXIT EVENT ===========================*/
39+
40+
SEC("tp_btf/sys_exit")
41+
int BPF_PROG(capset_x,
42+
struct pt_regs *regs,
43+
long ret)
44+
{
45+
struct ringbuf_struct ringbuf;
46+
if(!ringbuf__reserve_space(&ringbuf, CAPSET_X_SIZE))
47+
{
48+
return 0;
49+
}
50+
51+
ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_CAPSET_X, CAPSET_X_SIZE);
52+
53+
/*=============================== COLLECT PARAMETERS ===========================*/
54+
55+
/* Parameter 1: res (type: PT_ERRNO) */
56+
ringbuf__store_s64(&ringbuf, ret);
57+
58+
struct task_struct *task = get_current_task();
59+
60+
/* Parameter 2: cap_inheritable (type: PT_UINT64) */
61+
u64 cap_inheritable = extract__capability(task, CAP_INHERITABLE);
62+
ringbuf__store_u64(&ringbuf, cap_inheritable);
63+
64+
/* Parameter 3: cap_permitted (type: PT_UINT64) */
65+
u64 cap_permitted = extract__capability(task, CAP_PERMITTED);
66+
ringbuf__store_u64(&ringbuf, cap_permitted);
67+
68+
/* Parameter 4: cap_effective (type: PT_UINT64) */
69+
u64 cap_effective = extract__capability(task, CAP_EFFECTIVE);
70+
ringbuf__store_u64(&ringbuf, cap_effective);
71+
72+
/*=============================== COLLECT PARAMETERS ===========================*/
73+
74+
ringbuf__submit_event(&ringbuf);
75+
76+
return 0;
77+
}
78+
79+
/*=============================== EXIT EVENT ===========================*/
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include "../../event_class/event_class.h"
2+
3+
#ifdef __NR_capset
4+
5+
#include <sys/capability.h>
6+
7+
TEST(SyscallEnter, capsetE)
8+
{
9+
auto evt_test = new event_test(__NR_capset, ENTER_EVENT);
10+
11+
evt_test->enable_capture();
12+
13+
/*=============================== TRIGGER SYSCALL ===========================*/
14+
15+
/* - `cap_user_header_t` is a pointer to `__user_cap_header_struct`
16+
* - `cap_user_data_t` is a pointer to `__user_cap_data_struct`
17+
*/
18+
cap_user_header_t hdrp = NULL;
19+
cap_user_data_t datap = NULL;
20+
assert_syscall_state(SYSCALL_FAILURE, "capset", syscall(__NR_capset, hdrp, datap));
21+
22+
/*=============================== TRIGGER SYSCALL ===========================*/
23+
24+
evt_test->disable_capture();
25+
26+
evt_test->assert_event_presence();
27+
28+
if(HasFatalFailure())
29+
{
30+
return;
31+
}
32+
33+
evt_test->parse_event();
34+
35+
evt_test->assert_header();
36+
37+
/*=============================== ASSERT PARAMETERS ===========================*/
38+
39+
// Here we have no parameters to assert.
40+
41+
/*=============================== ASSERT PARAMETERS ===========================*/
42+
43+
evt_test->assert_num_params_pushed(0);
44+
}
45+
#endif

0 commit comments

Comments
 (0)