-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathgo_types.h
More file actions
91 lines (73 loc) · 2.52 KB
/
go_types.h
File metadata and controls
91 lines (73 loc) · 2.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include "alloc.h"
#include "bpf_helpers.h"
#define MAX_REALLOCATION 400
#define MAX_DATA_SIZE 400
struct go_string {
char* str;
s32 len;
};
struct go_slice {
void* array;
s32 len;
s32 cap;
};
struct go_slice_user_ptr {
void* array;
void* len;
void* cap;
};
struct go_iface {
void* tab;
void* data;
};
static __always_inline struct go_string write_user_go_string(char* str, u32 len) {
// Copy chars to userspace
char *addr = write_target_data((void*)str, len);
// Build string struct in kernel space
struct go_string new_string = {};
new_string.str = addr;
new_string.len = len;
// Copy new string struct to userspace
void* res = write_target_data((void*)&new_string, sizeof(new_string));
if (res == NULL) {
new_string.len = 0;
}
return new_string;
}
static __always_inline void append_item_to_slice(struct go_slice *slice, void* new_item, s32 item_size, struct go_slice_user_ptr *slice_user_ptr, void* buff) {
if (slice->len < slice->cap) {
// Room available on current array
bpf_probe_write_user(slice->array+(item_size*slice->len), new_item, item_size);
} else {
// No room on current array - copy to new one of size item_size * (len + 1)
if (slice->len > MAX_DATA_SIZE || slice->len < 1) {
return;
}
s32 alloc_size = item_size * slice->len;
s32 bounded_alloc_size = alloc_size > MAX_REALLOCATION ? MAX_REALLOCATION : (alloc_size < 1 ? 1 : alloc_size);
// Get buffer
s32 index = 0;
void* map_buff = bpf_map_lookup_elem(buff, &index);
if (!map_buff) {
return;
}
// Append to buffer
bpf_probe_read_user(map_buff, bounded_alloc_size, slice->array);
bpf_probe_read(map_buff+bounded_alloc_size, item_size, new_item);
// Copy buffer to userspace
u32 new_array_size = bounded_alloc_size+item_size;
if (new_array_size > MAX_DATA_SIZE || new_array_size < 1) {
return;
}
void* new_array = write_target_data(map_buff, new_array_size);
// Update array
slice->array = new_array;
long success = bpf_probe_write_user(slice_user_ptr->array, &slice->array, sizeof(slice->array));
// Update cap
slice->cap++;
success = bpf_probe_write_user(slice_user_ptr->cap, &slice->cap, sizeof(slice->cap));
}
// Update len
slice->len++;
long success = bpf_probe_write_user(slice_user_ptr->len, &slice->len, sizeof(slice->len));
}