1 // SPDX-License-Identifier: GPL-2.0 2 #define BPF_NO_KFUNC_PROTOTYPES 3 #include <vmlinux.h> 4 #include <bpf/bpf_tracing.h> 5 #include <bpf/bpf_helpers.h> 6 #include <bpf/bpf_core_read.h> 7 #include "bpf_misc.h" 8 9 struct nf_conn; 10 11 struct bpf_ct_opts___local { 12 s32 netns_id; 13 s32 error; 14 u8 l4proto; 15 u8 reserved[3]; 16 } __attribute__((preserve_access_index)); 17 18 struct nf_conn *bpf_skb_ct_alloc(struct __sk_buff *, struct bpf_sock_tuple *, u32, 19 struct bpf_ct_opts___local *, u32) __ksym; 20 struct nf_conn *bpf_skb_ct_lookup(struct __sk_buff *, struct bpf_sock_tuple *, u32, 21 struct bpf_ct_opts___local *, u32) __ksym; 22 struct nf_conn *bpf_xdp_ct_alloc(struct xdp_md *, struct bpf_sock_tuple *, u32, 23 struct bpf_ct_opts___local *, u32) __ksym; 24 struct nf_conn *bpf_xdp_ct_lookup(struct xdp_md *, struct bpf_sock_tuple *, u32, 25 struct bpf_ct_opts___local *, u32) __ksym; 26 struct nf_conn *bpf_ct_insert_entry(struct nf_conn *) __ksym; 27 void bpf_ct_release(struct nf_conn *) __ksym; 28 void bpf_ct_set_timeout(struct nf_conn *, u32) __ksym; 29 int bpf_ct_change_timeout(struct nf_conn *, u32) __ksym; 30 int bpf_ct_set_status(struct nf_conn *, u32) __ksym; 31 int bpf_ct_change_status(struct nf_conn *, u32) __ksym; 32 33 SEC("?tc") 34 int alloc_release(struct __sk_buff *ctx) 35 { 36 struct bpf_ct_opts___local opts = {}; 37 struct bpf_sock_tuple tup = {}; 38 struct nf_conn *ct; 39 40 ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts)); 41 if (!ct) 42 return 0; 43 bpf_ct_release(ct); 44 return 0; 45 } 46 47 SEC("?tc") 48 int insert_insert(struct __sk_buff *ctx) 49 { 50 struct bpf_ct_opts___local opts = {}; 51 struct bpf_sock_tuple tup = {}; 52 struct nf_conn *ct; 53 54 ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts)); 55 if (!ct) 56 return 0; 57 ct = bpf_ct_insert_entry(ct); 58 if (!ct) 59 return 0; 60 ct = bpf_ct_insert_entry(ct); 61 return 0; 62 } 63 64 SEC("?tc") 65 int lookup_insert(struct __sk_buff *ctx) 66 { 67 struct bpf_ct_opts___local opts = {}; 68 struct bpf_sock_tuple tup = {}; 69 struct nf_conn *ct; 70 71 ct = bpf_skb_ct_lookup(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts)); 72 if (!ct) 73 return 0; 74 bpf_ct_insert_entry(ct); 75 return 0; 76 } 77 78 SEC("?tc") 79 int write_not_allowlisted_field(struct __sk_buff *ctx) 80 { 81 struct bpf_ct_opts___local opts = {}; 82 struct bpf_sock_tuple tup = {}; 83 struct nf_conn *ct; 84 85 ct = bpf_skb_ct_lookup(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts)); 86 if (!ct) 87 return 0; 88 ct->status = 0xF00; 89 return 0; 90 } 91 92 SEC("?tc") 93 int set_timeout_after_insert(struct __sk_buff *ctx) 94 { 95 struct bpf_ct_opts___local opts = {}; 96 struct bpf_sock_tuple tup = {}; 97 struct nf_conn *ct; 98 99 ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts)); 100 if (!ct) 101 return 0; 102 ct = bpf_ct_insert_entry(ct); 103 if (!ct) 104 return 0; 105 bpf_ct_set_timeout(ct, 0); 106 return 0; 107 } 108 109 SEC("?tc") 110 int set_status_after_insert(struct __sk_buff *ctx) 111 { 112 struct bpf_ct_opts___local opts = {}; 113 struct bpf_sock_tuple tup = {}; 114 struct nf_conn *ct; 115 116 ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts)); 117 if (!ct) 118 return 0; 119 ct = bpf_ct_insert_entry(ct); 120 if (!ct) 121 return 0; 122 bpf_ct_set_status(ct, 0); 123 return 0; 124 } 125 126 SEC("?tc") 127 int change_timeout_after_alloc(struct __sk_buff *ctx) 128 { 129 struct bpf_ct_opts___local opts = {}; 130 struct bpf_sock_tuple tup = {}; 131 struct nf_conn *ct; 132 133 ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts)); 134 if (!ct) 135 return 0; 136 bpf_ct_change_timeout(ct, 0); 137 return 0; 138 } 139 140 SEC("?tc") 141 int change_status_after_alloc(struct __sk_buff *ctx) 142 { 143 struct bpf_ct_opts___local opts = {}; 144 struct bpf_sock_tuple tup = {}; 145 struct nf_conn *ct; 146 147 ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts)); 148 if (!ct) 149 return 0; 150 bpf_ct_change_status(ct, 0); 151 return 0; 152 } 153 154 SEC("?tc") 155 __failure __msg("Possibly NULL pointer passed to trusted arg1") 156 int lookup_null_bpf_tuple(struct __sk_buff *ctx) 157 { 158 struct bpf_ct_opts___local opts = {}; 159 struct nf_conn *ct; 160 161 ct = bpf_skb_ct_lookup(ctx, NULL, 0, &opts, sizeof(opts)); 162 if (ct) 163 bpf_ct_release(ct); 164 return 0; 165 } 166 167 SEC("?tc") 168 __failure __msg("Possibly NULL pointer passed to trusted arg3") 169 int lookup_null_bpf_opts(struct __sk_buff *ctx) 170 { 171 struct bpf_sock_tuple tup = {}; 172 struct nf_conn *ct; 173 174 ct = bpf_skb_ct_lookup(ctx, &tup, sizeof(tup.ipv4), NULL, sizeof(struct bpf_ct_opts___local)); 175 if (ct) 176 bpf_ct_release(ct); 177 return 0; 178 } 179 180 SEC("?xdp") 181 __failure __msg("Possibly NULL pointer passed to trusted arg1") 182 int xdp_lookup_null_bpf_tuple(struct xdp_md *ctx) 183 { 184 struct bpf_ct_opts___local opts = {}; 185 struct nf_conn *ct; 186 187 ct = bpf_xdp_ct_lookup(ctx, NULL, 0, &opts, sizeof(opts)); 188 if (ct) 189 bpf_ct_release(ct); 190 return 0; 191 } 192 193 SEC("?xdp") 194 __failure __msg("Possibly NULL pointer passed to trusted arg3") 195 int xdp_lookup_null_bpf_opts(struct xdp_md *ctx) 196 { 197 struct bpf_sock_tuple tup = {}; 198 struct nf_conn *ct; 199 200 ct = bpf_xdp_ct_lookup(ctx, &tup, sizeof(tup.ipv4), NULL, sizeof(struct bpf_ct_opts___local)); 201 if (ct) 202 bpf_ct_release(ct); 203 return 0; 204 } 205 206 char _license[] SEC("license") = "GPL"; 207