Skip to content

Commit 00662e0

Browse files
committed
feat: add PPME_SYSCALL_PPOLL_E params to PPME_SYSCALL_PPOLL_X
Add `PPME_SYSCALL_PPOLL_E` parameters to `PPME_SYSCALL_PPOLL_X` event definition and aligns all 3 kernel drivers to it. Add new rules to scap file converter table to convert events in old scap files to the new layout. Add/update ppoll-related drivers, scap converter and sinsp parser tests to account the new layout. Signed-off-by: Leonardo Di Giovanna <[email protected]>
1 parent 5f249d1 commit 00662e0

File tree

14 files changed

+273
-21
lines changed

14 files changed

+273
-21
lines changed

driver/SCHEMA_VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.40.0
1+
3.41.0

driver/bpf/fillers.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5419,15 +5419,12 @@ FILLER(sys_mount_e, true) {
54195419
}
54205420

54215421
FILLER(sys_ppoll_e, true) {
5422-
unsigned long val;
5423-
int res;
5424-
54255422
/* Parameter 1: fds (type: PT_FDLIST) */
5426-
res = bpf_poll_parse_fds(data, true);
5423+
int res = bpf_poll_parse_fds(data, true);
54275424
CHECK_RES(res);
54285425

54295426
/* Parameter 2: timeout (type: PT_RELTIME) */
5430-
val = bpf_syscall_get_argument(data, 2);
5427+
unsigned long val = bpf_syscall_get_argument(data, 2);
54315428
res = timespec_parse(data, val);
54325429
CHECK_RES(res);
54335430

@@ -5439,13 +5436,25 @@ FILLER(sys_ppoll_e, true) {
54395436
}
54405437

54415438
FILLER(sys_ppoll_x, true) {
5442-
/* Parameter 1: ret (type: PT_FD) */
5439+
/* Parameter 1: res (type: PT_ERRNO) */
54435440
long retval = bpf_syscall_get_retval(data->ctx);
54445441
int res = bpf_push_s64_to_ring(data, (int64_t)retval);
54455442
CHECK_RES(res);
54465443

54475444
/* Parameter 2: fds (type: PT_FDLIST) */
5448-
return bpf_poll_parse_fds(data, false);
5445+
res = bpf_poll_parse_fds(data, false);
5446+
CHECK_RES(res);
5447+
5448+
/* Parameter 3: timeout (type: PT_RELTIME) */
5449+
unsigned long val = bpf_syscall_get_argument(data, 2);
5450+
res = timespec_parse(data, val);
5451+
CHECK_RES(res);
5452+
5453+
/* Parameter 4: sigmask (type: PT_SIGSET) */
5454+
long unsigned int sigmask[1] = {0};
5455+
unsigned long sigmask_pointer = bpf_syscall_get_argument(data, 3);
5456+
bpf_probe_read_user(&sigmask, sizeof(sigmask), (void *)sigmask_pointer);
5457+
return bpf_push_u32_to_ring(data, sigmask[0]);
54495458
}
54505459

54515460
FILLER(sys_semop_x, true) {

driver/event_table.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1625,16 +1625,19 @@ const struct ppm_event_info g_event_info[] = {
16251625
{"val", PT_INT32, PF_DEC}}},
16261626
[PPME_SYSCALL_PPOLL_E] = {"ppoll",
16271627
EC_WAIT | EC_SYSCALL,
1628-
EF_WAITS,
1628+
EF_WAITS | EF_TMP_CONVERTER_MANAGED,
16291629
3,
16301630
{{"fds", PT_FDLIST, PF_DEC},
16311631
{"timeout", PT_RELTIME, PF_DEC},
16321632
{"sigmask", PT_SIGSET, PF_DEC}}},
16331633
[PPME_SYSCALL_PPOLL_X] = {"ppoll",
16341634
EC_WAIT | EC_SYSCALL,
1635-
EF_WAITS,
1636-
2,
1637-
{{"res", PT_ERRNO, PF_DEC}, {"fds", PT_FDLIST, PF_DEC}}},
1635+
EF_WAITS | EF_TMP_CONVERTER_MANAGED,
1636+
4,
1637+
{{"res", PT_ERRNO, PF_DEC},
1638+
{"fds", PT_FDLIST, PF_DEC},
1639+
{"timeout", PT_RELTIME, PF_DEC},
1640+
{"sigmask", PT_SIGSET, PF_DEC}}},
16381641
[PPME_SYSCALL_MOUNT_E] = {"mount",
16391642
EC_FILE | EC_SYSCALL,
16401643
EF_MODIFIES_STATE,

driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/ppoll.bpf.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ int BPF_PROG(ppoll_x, struct pt_regs *regs, long ret) {
8787

8888
/*=============================== COLLECT PARAMETERS ===========================*/
8989

90-
/* Parameter 1: ret (type: PT_FD) */
90+
/* Parameter 1: res (type: PT_ERRNO) */
9191
auxmap__store_s64_param(auxmap, ret);
9292

9393
/* Get the `fds_pointer` and the number of `fds` from the syscall arguments */
@@ -97,6 +97,38 @@ int BPF_PROG(ppoll_x, struct pt_regs *regs, long ret) {
9797
/* Parameter 2: fds (type: PT_FDLIST) */
9898
auxmap__store_fdlist_param(auxmap, fds_pointer, nfds, RETURNED_EVENTS);
9999

100+
/* Parameter 3: timeout (type: PT_RELTIME) */
101+
uint64_t nanosec = 0;
102+
unsigned long ts_pointer = extract__syscall_argument(regs, 2);
103+
if(!bpf_in_ia32_syscall()) {
104+
if(bpf_core_type_exists(struct __kernel_timespec)) {
105+
struct __kernel_timespec ts = {0};
106+
bpf_probe_read_user(&ts,
107+
bpf_core_type_size(struct __kernel_timespec),
108+
(void *)ts_pointer);
109+
nanosec = ((uint64_t)ts.tv_sec) * SECOND_TO_NS + ts.tv_nsec;
110+
} else {
111+
struct modern_bpf__kernel_timespec ts = {0};
112+
bpf_probe_read_user(&ts, sizeof(ts), (void *)ts_pointer);
113+
nanosec = ((uint64_t)ts.tv_sec) * SECOND_TO_NS + ts.tv_nsec;
114+
}
115+
} else {
116+
struct modern_bpf__kernel_timespec_ia32 ts = {0};
117+
bpf_probe_read_user(&ts, sizeof(ts), (void *)ts_pointer);
118+
nanosec = ((uint32_t)ts.tv_sec) * SECOND_TO_NS + ts.tv_nsec;
119+
}
120+
auxmap__store_u64_param(auxmap, nanosec);
121+
122+
/* Parameter 4: sigmask (type: PT_SIGSET) */
123+
long unsigned int sigmask[1] = {0};
124+
unsigned long sigmask_pointer = extract__syscall_argument(regs, 3);
125+
if(bpf_probe_read_user(&sigmask, sizeof(sigmask), (void *)sigmask_pointer)) {
126+
/* In case of invalid pointer, return 0 */
127+
auxmap__store_u32_param(auxmap, (uint32_t)0);
128+
} else {
129+
auxmap__store_u32_param(auxmap, (uint32_t)sigmask[0]);
130+
}
131+
100132
/*=============================== COLLECT PARAMETERS ===========================*/
101133

102134
auxmap__finalize_event_header(auxmap);

driver/ppm_fillers.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4162,8 +4162,8 @@ static int timespec_parse(struct event_filler_arguments *args, unsigned long val
41624162
}
41634163

41644164
int f_sys_ppoll_e(struct event_filler_arguments *args) {
4165-
unsigned long val = 0;
4166-
int res = 0;
4165+
int res;
4166+
unsigned long val;
41674167

41684168
/* Parameter 1: fds (type: PT_FDLIST) */
41694169
res = poll_parse_fds(args, true);
@@ -4188,16 +4188,30 @@ int f_sys_ppoll_e(struct event_filler_arguments *args) {
41884188
int f_sys_ppoll_x(struct event_filler_arguments *args) {
41894189
int64_t retval;
41904190
int res;
4191+
unsigned long val;
41914192

4192-
/* Parameter 1: ret (type: PT_FD) */
4193-
retval = (int64_t)(long)syscall_get_return_value(current, args->regs);
4193+
/* Parameter 1: res (type: PT_ERRNO) */
4194+
retval = (int64_t)syscall_get_return_value(current, args->regs);
41944195
res = val_to_ring(args, retval, 0, false, 0);
41954196
CHECK_RES(res);
41964197

41974198
/* Parameter 2: fds (type: PT_FDLIST) */
41984199
res = poll_parse_fds(args, false);
41994200
CHECK_RES(res);
42004201

4202+
/* Parameter 3: timeout (type: PT_RELTIME) */
4203+
syscall_get_arguments_deprecated(args, 2, 1, &val);
4204+
res = timespec_parse(args, val);
4205+
CHECK_RES(res);
4206+
4207+
/* Parameter 4: sigmask (type: PT_SIGSET) */
4208+
syscall_get_arguments_deprecated(args, 3, 1, &val);
4209+
if(val == (unsigned long)NULL || ppm_copy_from_user(&val, (void __user *)val, sizeof(val))) {
4210+
val = 0;
4211+
}
4212+
res = val_to_ring(args, (uint32_t)val, 0, false, 0);
4213+
CHECK_RES(res);
4214+
42014215
return add_sentinel(args);
42024216
}
42034217

test/drivers/test_suites/syscall_exit_suite/ppoll_x.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,16 @@ TEST(SyscallExit, ppollX) {
4646
/* The pointer is NULL so we should have no `fd` collected */
4747
evt_test->assert_fd_list(2, NULL, (uint16_t)0);
4848

49+
/* Parameter 2: timeout (type: PT_RELTIME) */
50+
/* The pointer is NULL so we should have `0` */
51+
evt_test->assert_numeric_param(3, (uint64_t)0);
52+
53+
/* Parameter 3: sigmask (type: PT_SIGSET) */
54+
/* The pointer is NULL so we should have `0` */
55+
evt_test->assert_numeric_param(4, (uint32_t)0);
56+
4957
/*=============================== ASSERT PARAMETERS ===========================*/
5058

51-
evt_test->assert_num_params_pushed(2);
59+
evt_test->assert_num_params_pushed(4);
5260
}
5361
#endif

test/libscap/test_suites/engines/savefile/converter.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2870,6 +2870,96 @@ TEST_F(convert_event_test, PPME_SYSCALL_SEMCTL_X_1_to_5_params_with_enter) {
28702870
val));
28712871
}
28722872

2873+
////////////////////////////
2874+
// PPOLL
2875+
////////////////////////////
2876+
2877+
TEST_F(convert_event_test, PPME_SYSCALL_PPOLL_E_store) {
2878+
constexpr uint64_t ts = 12;
2879+
constexpr int64_t tid = 25;
2880+
2881+
constexpr uint8_t fds[] = {0x1, 0x0, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0};
2882+
constexpr uint64_t timeout = 30;
2883+
constexpr uint32_t sigmask = 31;
2884+
2885+
const auto evt = create_safe_scap_event(ts,
2886+
tid,
2887+
PPME_SYSCALL_PPOLL_E,
2888+
3,
2889+
scap_const_sized_buffer{fds, sizeof(fds)},
2890+
timeout,
2891+
sigmask);
2892+
assert_single_conversion_skip(evt);
2893+
assert_event_storage_presence(evt);
2894+
}
2895+
2896+
TEST_F(convert_event_test, PPME_SYSCALL_PPOLL_X_2_to_4_params_no_enter) {
2897+
constexpr uint64_t ts = 12;
2898+
constexpr int64_t tid = 25;
2899+
2900+
constexpr int64_t res = 89;
2901+
constexpr uint8_t fds[] = {0x1, 0x0, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0};
2902+
2903+
// Defaulted to 0
2904+
constexpr uint64_t timeout = 0;
2905+
constexpr uint32_t sigmask = 0;
2906+
2907+
assert_single_conversion_success(
2908+
conversion_result::CONVERSION_COMPLETED,
2909+
create_safe_scap_event(ts,
2910+
tid,
2911+
PPME_SYSCALL_PPOLL_X,
2912+
2,
2913+
res,
2914+
scap_const_sized_buffer{fds, sizeof(fds)}),
2915+
create_safe_scap_event(ts,
2916+
tid,
2917+
PPME_SYSCALL_PPOLL_X,
2918+
4,
2919+
res,
2920+
scap_const_sized_buffer{fds, sizeof(fds)},
2921+
timeout,
2922+
sigmask));
2923+
}
2924+
2925+
TEST_F(convert_event_test, PPME_SYSCALL_PPOLL_X_2_to_4_params_with_enter) {
2926+
constexpr uint64_t ts = 12;
2927+
constexpr int64_t tid = 25;
2928+
2929+
constexpr uint8_t fds[] = {0x1, 0x0, 0x16, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0};
2930+
constexpr uint64_t timeout = 30;
2931+
constexpr uint32_t sigmask = 31;
2932+
constexpr int64_t res = 89;
2933+
2934+
// After the first conversion we should have the storage
2935+
const auto evt = create_safe_scap_event(ts,
2936+
tid,
2937+
PPME_SYSCALL_PPOLL_E,
2938+
3,
2939+
scap_const_sized_buffer{fds, sizeof(fds)},
2940+
timeout,
2941+
sigmask);
2942+
assert_single_conversion_skip(evt);
2943+
assert_event_storage_presence(evt);
2944+
2945+
assert_single_conversion_success(
2946+
conversion_result::CONVERSION_COMPLETED,
2947+
create_safe_scap_event(ts,
2948+
tid,
2949+
PPME_SYSCALL_PPOLL_X,
2950+
2,
2951+
res,
2952+
scap_const_sized_buffer{fds, sizeof(fds)}),
2953+
create_safe_scap_event(ts,
2954+
tid,
2955+
PPME_SYSCALL_PPOLL_X,
2956+
4,
2957+
res,
2958+
scap_const_sized_buffer{fds, sizeof(fds)},
2959+
timeout,
2960+
sigmask));
2961+
}
2962+
28732963
////////////////////////////
28742964
// SEMGET
28752965
////////////////////////////

test/libsinsp_e2e/sys_call_test.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1385,7 +1385,8 @@ TEST_F(sys_call_test, ppoll_timeout) {
13851385
string fds = e->get_param_value_str("fds");
13861386

13871387
EXPECT_TRUE(fds == "3:p0 4:p4" || fds == "4:p0 5:p4");
1388-
1388+
EXPECT_EQ("1000000", e->get_param_value_str("timeout", false));
1389+
EXPECT_EQ("SIGHUP SIGCHLD", e->get_param_value_str("sigmask", false));
13891390
callnum++;
13901391
}
13911392
};
@@ -2087,6 +2088,8 @@ TEST_F(sys_call_test32, ppoll_timeout) {
20872088
FAIL();
20882089
}
20892090

2091+
EXPECT_EQ("1000000", e->get_param_value_str("timeout", false));
2092+
EXPECT_EQ("SIGHUP SIGCHLD", e->get_param_value_str("sigmask", false));
20902093
callnum++;
20912094
}
20922095
};

userspace/libscap/engine/savefile/converter/converter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ static inline uint8_t get_size_bytes_from_type(enum ppm_param_type t) {
142142
case PT_UID:
143143
case PT_GID:
144144
case PT_MODE:
145+
case PT_SIGSET:
145146
return 4;
146147

147148
case PT_INT64:

userspace/libscap/engine/savefile/converter/table.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,12 @@ const std::unordered_map<conversion_key, conversion_info> g_conversion_table = {
293293
{C_INSTR_FROM_ENTER, 1},
294294
{C_INSTR_FROM_ENTER, 2},
295295
{C_INSTR_FROM_ENTER, 3}})},
296+
/*====================== PPOLL ======================*/
297+
{conversion_key{PPME_SYSCALL_PPOLL_E, 3}, conversion_info().action(C_ACTION_STORE)},
298+
{conversion_key{PPME_SYSCALL_PPOLL_X, 2},
299+
conversion_info()
300+
.action(C_ACTION_ADD_PARAMS)
301+
.instrs({{C_INSTR_FROM_ENTER, 1}, {C_INSTR_FROM_ENTER, 2}})},
296302
/*====================== SEMGET ======================*/
297303
{conversion_key{PPME_SYSCALL_SEMGET_E, 3}, conversion_info().action(C_ACTION_STORE)},
298304
{conversion_key{PPME_SYSCALL_SEMGET_X, 1},

0 commit comments

Comments
 (0)