From 35f46a1cadbd45ede579c7c52cf158fff7566362 Mon Sep 17 00:00:00 2001 From: Andrei Fedotov Date: Thu, 18 Jul 2024 12:51:09 +0300 Subject: [PATCH] bpf: Add postfix/notpostfix operator for matching binaries Adding postfix/notpostfix cases to match_binaries function allows to support postfix operator in matchBinaries selector. Signed-off-by: Andrei Fedotov --- bpf/process/types/basic.h | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/bpf/process/types/basic.h b/bpf/process/types/basic.h index 74a0d44c849..c54456c10ca 100644 --- a/bpf/process/types/basic.h +++ b/bpf/process/types/basic.h @@ -826,9 +826,6 @@ filter_char_buf_prefix(struct selector_arg_filter *filter, char *arg_str, uint a return !!pass; } -// Define a mask for the maximum path length on Linux. -#define PATH_MASK (4096 - 1) - FUNC_INLINE void copy_reverse(__u8 *dest, uint len, __u8 *src, uint offset) { uint i; @@ -848,7 +845,7 @@ FUNC_INLINE void copy_reverse(__u8 *dest, uint len, __u8 *src, uint offset) // Alternative (prettier) fixes resulted in a confused verifier // unfortunately. for (i = 0; i < (STRING_POSTFIX_MAX_MATCH_LENGTH - 1); i++) { - dest[i & STRING_POSTFIX_MAX_MASK] = src[(len + offset - 1 - i) & PATH_MASK]; + dest[i & STRING_POSTFIX_MAX_MASK] = src[(len + offset - 1 - i) & (BINARY_PATH_MAX_LEN - 1)]; if (len + offset == (i + 1)) return; } @@ -1554,6 +1551,9 @@ FUNC_INLINE int match_binaries(__u32 selidx) __u8 *found_key; #ifdef __LARGE_BPF_PROG struct string_prefix_lpm_trie prefix_key; + struct string_postfix_lpm_trie *postfix_key; + uint postfix_len = 0; + int zero = 0; long ret; #endif /* __LARGE_BPF_PROG */ @@ -1599,6 +1599,21 @@ FUNC_INLINE int match_binaries(__u32 selidx) return 0; found_key = map_lookup_elem(path_map, &prefix_key); break; + case op_filter_str_postfix: + case op_filter_str_notpostfix: + postfix_len = current->bin.path_length; + path_map = map_lookup_elem(&string_postfix_maps, &selector_options->map_id); + if (!path_map || !postfix_len) + return 0; + if (postfix_len >= STRING_POSTFIX_MAX_MATCH_LENGTH) + postfix_len = STRING_POSTFIX_MAX_MATCH_LENGTH - 1; + postfix_key = (struct string_postfix_lpm_trie *)map_lookup_elem(&string_postfix_maps_heap, &zero); + if (!postfix_key) + return 0; + postfix_key->prefixlen = postfix_len * 8; // prefixlen is in bits + copy_reverse(postfix_key->data, postfix_len, (__u8 *)current->bin.path, current->bin.path_length - postfix_len); + found_key = map_lookup_elem(path_map, postfix_key); + break; #endif /* __LARGE_BPF_PROG */ default: // should not happen