@@ -22,27 +22,30 @@ struct result_t {
22
22
};
23
23
24
24
// extract "User-Agent"
25
- // don't true the result if the request is coming from user
25
+ // don't trust the result if the request is coming from user
26
26
static __always_inline int extract_user_agent_header (
27
27
struct __sk_buff * skb , u32 offset , int msg_len , struct result_t * result ) {
28
28
int i , start_pos = -1 ;
29
29
long err ;
30
+ u32 initial_offset = offset ; // Store initial offset for later use
30
31
32
+ // Limit search length to prevent excessive processing
31
33
int search_len = msg_len ;
32
34
if (search_len > MAX_HEADER_LEN ) {
33
35
search_len = MAX_HEADER_LEN ;
34
36
}
35
37
38
+ // Search for "User-Agent: " header (12 characters)
36
39
char word [] = "User-Agent: " ;
37
40
#pragma unroll
38
- for (i = 0 ; i <= search_len - 8 ; i ++ ) {
41
+ for (i = 0 ; i <= search_len - 12 ; i ++ ) {
39
42
err = bpf_skb_load_bytes (skb , offset , & word , sizeof (word )- 1 );
40
43
if (err < 0 ) {
41
44
bpf_printk ("BPF read word failed at offset %d, err %d" , offset , err );
42
45
break ;
43
46
}
44
47
bpf_printk ("offset %d, word: %s" , offset , word );
45
- // "User-Agent: "
48
+ // Check for exact match with "User-Agent: "
46
49
if (word [0 ] == 'U' && word [1 ] == 's' && word [2 ] == 'e' &&
47
50
word [3 ] == 'r' && word [4 ] == '-' && word [5 ] == 'A' &&
48
51
word [6 ] == 'g' && word [7 ] == 'e' && word [8 ] == 'n' &&
@@ -53,32 +56,35 @@ static __always_inline int extract_user_agent_header(
53
56
offset ++ ;
54
57
}
55
58
59
+ // If "User-Agent: " not found, return error
56
60
if (start_pos < 0 ) {
57
- bpf_printk ("'User-Agent: ' not found" ); // Optional debug print
58
- return -1 ; // Pattern not found
61
+ bpf_printk ("'User-Agent: ' not found" );
62
+ return -1 ;
59
63
}
64
+
65
+ // Check if there's enough data to read User-Agent value
60
66
if (search_len - start_pos <= 0 ) {
61
67
bpf_printk ("invalid data" );
62
68
return -1 ;
63
69
}
70
+ offset = initial_offset + start_pos ;
64
71
72
+ // Read the User-Agent value until CR, LF or buffer full
65
73
int j = 0 ;
66
74
#pragma unroll
67
- for (j = 0 ; j <= search_len - start_pos ; j ++ ) {
75
+ for (j = 0 ; j <= MAX_VALUE_SIZE - 1 && j <= search_len - start_pos ; j ++ ) {
68
76
char c ;
69
- err = bpf_skb_load_bytes (skb , offset , & c , sizeof (c ));
77
+ err = bpf_skb_load_bytes (skb , offset + j , & c , sizeof (c ));
70
78
if (err < 0 ) {
71
- bpf_printk ("BPF read word failed at offset %d, err %d" , i , err );
79
+ bpf_printk ("BPF read failed at offset %d, err %d" , offset + j , err );
72
80
break ;
73
81
}
74
- offset ++ ;
82
+
83
+ // Stop at line break
75
84
if (c == '\r' || c == '\n' ) {
76
85
break ;
77
86
}
78
- if (j >= MAX_VALUE_SIZE - 1 ) {
79
- bpf_printk ("Buffer overflow" );
80
- break ;
81
- }
87
+
82
88
result -> value [j ] = c ;
83
89
}
84
90
result -> value [j ] = '\0' ; // Null-terminate the string
0 commit comments