Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Alexei Starovoitov says:

====================
pull-request: bpf-next 2021-12-30

The following pull-request contains BPF updates for your *net-next* tree.

We've added 72 non-merge commits during the last 20 day(s) which contain
a total of 223 files changed, 3510 insertions(+), 1591 deletions(-).

The main changes are:

1) Automatic setrlimit in libbpf when bpf is memcg's in the kernel, from Andrii.

2) Beautify and de-verbose verifier logs, from Christy.

3) Composable verifier types, from Hao.

4) bpf_strncmp helper, from Hou.

5) bpf.h header dependency cleanup, from Jakub.

6) get_func_[arg|ret|arg_cnt] helpers, from Jiri.

7) Sleepable local storage, from KP.

8) Extend kfunc with PTR_TO_CTX, PTR_TO_MEM argument support, from Kumar.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+3501 -1586
+376
Documentation/bpf/classic_vs_extended.rst
··· 1 + 2 + =================== 3 + Classic BPF vs eBPF 4 + =================== 5 + 6 + eBPF is designed to be JITed with one to one mapping, which can also open up 7 + the possibility for GCC/LLVM compilers to generate optimized eBPF code through 8 + an eBPF backend that performs almost as fast as natively compiled code. 9 + 10 + Some core changes of the eBPF format from classic BPF: 11 + 12 + - Number of registers increase from 2 to 10: 13 + 14 + The old format had two registers A and X, and a hidden frame pointer. The 15 + new layout extends this to be 10 internal registers and a read-only frame 16 + pointer. Since 64-bit CPUs are passing arguments to functions via registers 17 + the number of args from eBPF program to in-kernel function is restricted 18 + to 5 and one register is used to accept return value from an in-kernel 19 + function. Natively, x86_64 passes first 6 arguments in registers, aarch64/ 20 + sparcv9/mips64 have 7 - 8 registers for arguments; x86_64 has 6 callee saved 21 + registers, and aarch64/sparcv9/mips64 have 11 or more callee saved registers. 22 + 23 + Thus, all eBPF registers map one to one to HW registers on x86_64, aarch64, 24 + etc, and eBPF calling convention maps directly to ABIs used by the kernel on 25 + 64-bit architectures. 26 + 27 + On 32-bit architectures JIT may map programs that use only 32-bit arithmetic 28 + and may let more complex programs to be interpreted. 29 + 30 + R0 - R5 are scratch registers and eBPF program needs spill/fill them if 31 + necessary across calls. Note that there is only one eBPF program (== one 32 + eBPF main routine) and it cannot call other eBPF functions, it can only 33 + call predefined in-kernel functions, though. 34 + 35 + - Register width increases from 32-bit to 64-bit: 36 + 37 + Still, the semantics of the original 32-bit ALU operations are preserved 38 + via 32-bit subregisters. All eBPF registers are 64-bit with 32-bit lower 39 + subregisters that zero-extend into 64-bit if they are being written to. 40 + That behavior maps directly to x86_64 and arm64 subregister definition, but 41 + makes other JITs more difficult. 42 + 43 + 32-bit architectures run 64-bit eBPF programs via interpreter. 44 + Their JITs may convert BPF programs that only use 32-bit subregisters into 45 + native instruction set and let the rest being interpreted. 46 + 47 + Operation is 64-bit, because on 64-bit architectures, pointers are also 48 + 64-bit wide, and we want to pass 64-bit values in/out of kernel functions, 49 + so 32-bit eBPF registers would otherwise require to define register-pair 50 + ABI, thus, there won't be able to use a direct eBPF register to HW register 51 + mapping and JIT would need to do combine/split/move operations for every 52 + register in and out of the function, which is complex, bug prone and slow. 53 + Another reason is the use of atomic 64-bit counters. 54 + 55 + - Conditional jt/jf targets replaced with jt/fall-through: 56 + 57 + While the original design has constructs such as ``if (cond) jump_true; 58 + else jump_false;``, they are being replaced into alternative constructs like 59 + ``if (cond) jump_true; /* else fall-through */``. 60 + 61 + - Introduces bpf_call insn and register passing convention for zero overhead 62 + calls from/to other kernel functions: 63 + 64 + Before an in-kernel function call, the eBPF program needs to 65 + place function arguments into R1 to R5 registers to satisfy calling 66 + convention, then the interpreter will take them from registers and pass 67 + to in-kernel function. If R1 - R5 registers are mapped to CPU registers 68 + that are used for argument passing on given architecture, the JIT compiler 69 + doesn't need to emit extra moves. Function arguments will be in the correct 70 + registers and BPF_CALL instruction will be JITed as single 'call' HW 71 + instruction. This calling convention was picked to cover common call 72 + situations without performance penalty. 73 + 74 + After an in-kernel function call, R1 - R5 are reset to unreadable and R0 has 75 + a return value of the function. Since R6 - R9 are callee saved, their state 76 + is preserved across the call. 77 + 78 + For example, consider three C functions:: 79 + 80 + u64 f1() { return (*_f2)(1); } 81 + u64 f2(u64 a) { return f3(a + 1, a); } 82 + u64 f3(u64 a, u64 b) { return a - b; } 83 + 84 + GCC can compile f1, f3 into x86_64:: 85 + 86 + f1: 87 + movl $1, %edi 88 + movq _f2(%rip), %rax 89 + jmp *%rax 90 + f3: 91 + movq %rdi, %rax 92 + subq %rsi, %rax 93 + ret 94 + 95 + Function f2 in eBPF may look like:: 96 + 97 + f2: 98 + bpf_mov R2, R1 99 + bpf_add R1, 1 100 + bpf_call f3 101 + bpf_exit 102 + 103 + If f2 is JITed and the pointer stored to ``_f2``. The calls f1 -> f2 -> f3 and 104 + returns will be seamless. Without JIT, __bpf_prog_run() interpreter needs to 105 + be used to call into f2. 106 + 107 + For practical reasons all eBPF programs have only one argument 'ctx' which is 108 + already placed into R1 (e.g. on __bpf_prog_run() startup) and the programs 109 + can call kernel functions with up to 5 arguments. Calls with 6 or more arguments 110 + are currently not supported, but these restrictions can be lifted if necessary 111 + in the future. 112 + 113 + On 64-bit architectures all register map to HW registers one to one. For 114 + example, x86_64 JIT compiler can map them as ... 115 + 116 + :: 117 + 118 + R0 - rax 119 + R1 - rdi 120 + R2 - rsi 121 + R3 - rdx 122 + R4 - rcx 123 + R5 - r8 124 + R6 - rbx 125 + R7 - r13 126 + R8 - r14 127 + R9 - r15 128 + R10 - rbp 129 + 130 + ... since x86_64 ABI mandates rdi, rsi, rdx, rcx, r8, r9 for argument passing 131 + and rbx, r12 - r15 are callee saved. 132 + 133 + Then the following eBPF pseudo-program:: 134 + 135 + bpf_mov R6, R1 /* save ctx */ 136 + bpf_mov R2, 2 137 + bpf_mov R3, 3 138 + bpf_mov R4, 4 139 + bpf_mov R5, 5 140 + bpf_call foo 141 + bpf_mov R7, R0 /* save foo() return value */ 142 + bpf_mov R1, R6 /* restore ctx for next call */ 143 + bpf_mov R2, 6 144 + bpf_mov R3, 7 145 + bpf_mov R4, 8 146 + bpf_mov R5, 9 147 + bpf_call bar 148 + bpf_add R0, R7 149 + bpf_exit 150 + 151 + After JIT to x86_64 may look like:: 152 + 153 + push %rbp 154 + mov %rsp,%rbp 155 + sub $0x228,%rsp 156 + mov %rbx,-0x228(%rbp) 157 + mov %r13,-0x220(%rbp) 158 + mov %rdi,%rbx 159 + mov $0x2,%esi 160 + mov $0x3,%edx 161 + mov $0x4,%ecx 162 + mov $0x5,%r8d 163 + callq foo 164 + mov %rax,%r13 165 + mov %rbx,%rdi 166 + mov $0x6,%esi 167 + mov $0x7,%edx 168 + mov $0x8,%ecx 169 + mov $0x9,%r8d 170 + callq bar 171 + add %r13,%rax 172 + mov -0x228(%rbp),%rbx 173 + mov -0x220(%rbp),%r13 174 + leaveq 175 + retq 176 + 177 + Which is in this example equivalent in C to:: 178 + 179 + u64 bpf_filter(u64 ctx) 180 + { 181 + return foo(ctx, 2, 3, 4, 5) + bar(ctx, 6, 7, 8, 9); 182 + } 183 + 184 + In-kernel functions foo() and bar() with prototype: u64 (*)(u64 arg1, u64 185 + arg2, u64 arg3, u64 arg4, u64 arg5); will receive arguments in proper 186 + registers and place their return value into ``%rax`` which is R0 in eBPF. 187 + Prologue and epilogue are emitted by JIT and are implicit in the 188 + interpreter. R0-R5 are scratch registers, so eBPF program needs to preserve 189 + them across the calls as defined by calling convention. 190 + 191 + For example the following program is invalid:: 192 + 193 + bpf_mov R1, 1 194 + bpf_call foo 195 + bpf_mov R0, R1 196 + bpf_exit 197 + 198 + After the call the registers R1-R5 contain junk values and cannot be read. 199 + An in-kernel verifier.rst is used to validate eBPF programs. 200 + 201 + Also in the new design, eBPF is limited to 4096 insns, which means that any 202 + program will terminate quickly and will only call a fixed number of kernel 203 + functions. Original BPF and eBPF are two operand instructions, 204 + which helps to do one-to-one mapping between eBPF insn and x86 insn during JIT. 205 + 206 + The input context pointer for invoking the interpreter function is generic, 207 + its content is defined by a specific use case. For seccomp register R1 points 208 + to seccomp_data, for converted BPF filters R1 points to a skb. 209 + 210 + A program, that is translated internally consists of the following elements:: 211 + 212 + op:16, jt:8, jf:8, k:32 ==> op:8, dst_reg:4, src_reg:4, off:16, imm:32 213 + 214 + So far 87 eBPF instructions were implemented. 8-bit 'op' opcode field 215 + has room for new instructions. Some of them may use 16/24/32 byte encoding. New 216 + instructions must be multiple of 8 bytes to preserve backward compatibility. 217 + 218 + eBPF is a general purpose RISC instruction set. Not every register and 219 + every instruction are used during translation from original BPF to eBPF. 220 + For example, socket filters are not using ``exclusive add`` instruction, but 221 + tracing filters may do to maintain counters of events, for example. Register R9 222 + is not used by socket filters either, but more complex filters may be running 223 + out of registers and would have to resort to spill/fill to stack. 224 + 225 + eBPF can be used as a generic assembler for last step performance 226 + optimizations, socket filters and seccomp are using it as assembler. Tracing 227 + filters may use it as assembler to generate code from kernel. In kernel usage 228 + may not be bounded by security considerations, since generated eBPF code 229 + may be optimizing internal code path and not being exposed to the user space. 230 + Safety of eBPF can come from the verifier.rst. In such use cases as 231 + described, it may be used as safe instruction set. 232 + 233 + Just like the original BPF, eBPF runs within a controlled environment, 234 + is deterministic and the kernel can easily prove that. The safety of the program 235 + can be determined in two steps: first step does depth-first-search to disallow 236 + loops and other CFG validation; second step starts from the first insn and 237 + descends all possible paths. It simulates execution of every insn and observes 238 + the state change of registers and stack. 239 + 240 + opcode encoding 241 + =============== 242 + 243 + eBPF is reusing most of the opcode encoding from classic to simplify conversion 244 + of classic BPF to eBPF. 245 + 246 + For arithmetic and jump instructions the 8-bit 'code' field is divided into three 247 + parts:: 248 + 249 + +----------------+--------+--------------------+ 250 + | 4 bits | 1 bit | 3 bits | 251 + | operation code | source | instruction class | 252 + +----------------+--------+--------------------+ 253 + (MSB) (LSB) 254 + 255 + Three LSB bits store instruction class which is one of: 256 + 257 + =================== =============== 258 + Classic BPF classes eBPF classes 259 + =================== =============== 260 + BPF_LD 0x00 BPF_LD 0x00 261 + BPF_LDX 0x01 BPF_LDX 0x01 262 + BPF_ST 0x02 BPF_ST 0x02 263 + BPF_STX 0x03 BPF_STX 0x03 264 + BPF_ALU 0x04 BPF_ALU 0x04 265 + BPF_JMP 0x05 BPF_JMP 0x05 266 + BPF_RET 0x06 BPF_JMP32 0x06 267 + BPF_MISC 0x07 BPF_ALU64 0x07 268 + =================== =============== 269 + 270 + The 4th bit encodes the source operand ... 271 + 272 + :: 273 + 274 + BPF_K 0x00 275 + BPF_X 0x08 276 + 277 + * in classic BPF, this means:: 278 + 279 + BPF_SRC(code) == BPF_X - use register X as source operand 280 + BPF_SRC(code) == BPF_K - use 32-bit immediate as source operand 281 + 282 + * in eBPF, this means:: 283 + 284 + BPF_SRC(code) == BPF_X - use 'src_reg' register as source operand 285 + BPF_SRC(code) == BPF_K - use 32-bit immediate as source operand 286 + 287 + ... and four MSB bits store operation code. 288 + 289 + If BPF_CLASS(code) == BPF_ALU or BPF_ALU64 [ in eBPF ], BPF_OP(code) is one of:: 290 + 291 + BPF_ADD 0x00 292 + BPF_SUB 0x10 293 + BPF_MUL 0x20 294 + BPF_DIV 0x30 295 + BPF_OR 0x40 296 + BPF_AND 0x50 297 + BPF_LSH 0x60 298 + BPF_RSH 0x70 299 + BPF_NEG 0x80 300 + BPF_MOD 0x90 301 + BPF_XOR 0xa0 302 + BPF_MOV 0xb0 /* eBPF only: mov reg to reg */ 303 + BPF_ARSH 0xc0 /* eBPF only: sign extending shift right */ 304 + BPF_END 0xd0 /* eBPF only: endianness conversion */ 305 + 306 + If BPF_CLASS(code) == BPF_JMP or BPF_JMP32 [ in eBPF ], BPF_OP(code) is one of:: 307 + 308 + BPF_JA 0x00 /* BPF_JMP only */ 309 + BPF_JEQ 0x10 310 + BPF_JGT 0x20 311 + BPF_JGE 0x30 312 + BPF_JSET 0x40 313 + BPF_JNE 0x50 /* eBPF only: jump != */ 314 + BPF_JSGT 0x60 /* eBPF only: signed '>' */ 315 + BPF_JSGE 0x70 /* eBPF only: signed '>=' */ 316 + BPF_CALL 0x80 /* eBPF BPF_JMP only: function call */ 317 + BPF_EXIT 0x90 /* eBPF BPF_JMP only: function return */ 318 + BPF_JLT 0xa0 /* eBPF only: unsigned '<' */ 319 + BPF_JLE 0xb0 /* eBPF only: unsigned '<=' */ 320 + BPF_JSLT 0xc0 /* eBPF only: signed '<' */ 321 + BPF_JSLE 0xd0 /* eBPF only: signed '<=' */ 322 + 323 + So BPF_ADD | BPF_X | BPF_ALU means 32-bit addition in both classic BPF 324 + and eBPF. There are only two registers in classic BPF, so it means A += X. 325 + In eBPF it means dst_reg = (u32) dst_reg + (u32) src_reg; similarly, 326 + BPF_XOR | BPF_K | BPF_ALU means A ^= imm32 in classic BPF and analogous 327 + src_reg = (u32) src_reg ^ (u32) imm32 in eBPF. 328 + 329 + Classic BPF is using BPF_MISC class to represent A = X and X = A moves. 330 + eBPF is using BPF_MOV | BPF_X | BPF_ALU code instead. Since there are no 331 + BPF_MISC operations in eBPF, the class 7 is used as BPF_ALU64 to mean 332 + exactly the same operations as BPF_ALU, but with 64-bit wide operands 333 + instead. So BPF_ADD | BPF_X | BPF_ALU64 means 64-bit addition, i.e.: 334 + dst_reg = dst_reg + src_reg 335 + 336 + Classic BPF wastes the whole BPF_RET class to represent a single ``ret`` 337 + operation. Classic BPF_RET | BPF_K means copy imm32 into return register 338 + and perform function exit. eBPF is modeled to match CPU, so BPF_JMP | BPF_EXIT 339 + in eBPF means function exit only. The eBPF program needs to store return 340 + value into register R0 before doing a BPF_EXIT. Class 6 in eBPF is used as 341 + BPF_JMP32 to mean exactly the same operations as BPF_JMP, but with 32-bit wide 342 + operands for the comparisons instead. 343 + 344 + For load and store instructions the 8-bit 'code' field is divided as:: 345 + 346 + +--------+--------+-------------------+ 347 + | 3 bits | 2 bits | 3 bits | 348 + | mode | size | instruction class | 349 + +--------+--------+-------------------+ 350 + (MSB) (LSB) 351 + 352 + Size modifier is one of ... 353 + 354 + :: 355 + 356 + BPF_W 0x00 /* word */ 357 + BPF_H 0x08 /* half word */ 358 + BPF_B 0x10 /* byte */ 359 + BPF_DW 0x18 /* eBPF only, double word */ 360 + 361 + ... which encodes size of load/store operation:: 362 + 363 + B - 1 byte 364 + H - 2 byte 365 + W - 4 byte 366 + DW - 8 byte (eBPF only) 367 + 368 + Mode modifier is one of:: 369 + 370 + BPF_IMM 0x00 /* used for 32-bit mov in classic BPF and 64-bit in eBPF */ 371 + BPF_ABS 0x20 372 + BPF_IND 0x40 373 + BPF_MEM 0x60 374 + BPF_LEN 0x80 /* classic BPF only, reserved in eBPF */ 375 + BPF_MSH 0xa0 /* classic BPF only, reserved in eBPF */ 376 + BPF_ATOMIC 0xc0 /* eBPF only, atomic operations */
+1
Documentation/bpf/index.rst
··· 21 21 helpers 22 22 programs 23 23 maps 24 + classic_vs_extended.rst 24 25 bpf_licensing 25 26 test_debug 26 27 other
+147 -361
Documentation/bpf/instruction-set.rst
··· 3 3 eBPF Instruction Set 4 4 ==================== 5 5 6 - eBPF is designed to be JITed with one to one mapping, which can also open up 7 - the possibility for GCC/LLVM compilers to generate optimized eBPF code through 8 - an eBPF backend that performs almost as fast as natively compiled code. 6 + Registers and calling convention 7 + ================================ 9 8 10 - Some core changes of the eBPF format from classic BPF: 9 + eBPF has 10 general purpose registers and a read-only frame pointer register, 10 + all of which are 64-bits wide. 11 11 12 - - Number of registers increase from 2 to 10: 12 + The eBPF calling convention is defined as: 13 13 14 - The old format had two registers A and X, and a hidden frame pointer. The 15 - new layout extends this to be 10 internal registers and a read-only frame 16 - pointer. Since 64-bit CPUs are passing arguments to functions via registers 17 - the number of args from eBPF program to in-kernel function is restricted 18 - to 5 and one register is used to accept return value from an in-kernel 19 - function. Natively, x86_64 passes first 6 arguments in registers, aarch64/ 20 - sparcv9/mips64 have 7 - 8 registers for arguments; x86_64 has 6 callee saved 21 - registers, and aarch64/sparcv9/mips64 have 11 or more callee saved registers. 14 + * R0: return value from function calls, and exit value for eBPF programs 15 + * R1 - R5: arguments for function calls 16 + * R6 - R9: callee saved registers that function calls will preserve 17 + * R10: read-only frame pointer to access stack 22 18 23 - Therefore, eBPF calling convention is defined as: 19 + R0 - R5 are scratch registers and eBPF programs needs to spill/fill them if 20 + necessary across calls. 24 21 25 - * R0 - return value from in-kernel function, and exit value for eBPF program 26 - * R1 - R5 - arguments from eBPF program to in-kernel function 27 - * R6 - R9 - callee saved registers that in-kernel function will preserve 28 - * R10 - read-only frame pointer to access stack 22 + Instruction classes 23 + =================== 29 24 30 - Thus, all eBPF registers map one to one to HW registers on x86_64, aarch64, 31 - etc, and eBPF calling convention maps directly to ABIs used by the kernel on 32 - 64-bit architectures. 25 + The three LSB bits of the 'opcode' field store the instruction class: 33 26 34 - On 32-bit architectures JIT may map programs that use only 32-bit arithmetic 35 - and may let more complex programs to be interpreted. 27 + ========= ===== 28 + class value 29 + ========= ===== 30 + BPF_LD 0x00 31 + BPF_LDX 0x01 32 + BPF_ST 0x02 33 + BPF_STX 0x03 34 + BPF_ALU 0x04 35 + BPF_JMP 0x05 36 + BPF_JMP32 0x06 37 + BPF_ALU64 0x07 38 + ========= ===== 36 39 37 - R0 - R5 are scratch registers and eBPF program needs spill/fill them if 38 - necessary across calls. Note that there is only one eBPF program (== one 39 - eBPF main routine) and it cannot call other eBPF functions, it can only 40 - call predefined in-kernel functions, though. 40 + Arithmetic and jump instructions 41 + ================================ 41 42 42 - - Register width increases from 32-bit to 64-bit: 43 + For arithmetic and jump instructions (BPF_ALU, BPF_ALU64, BPF_JMP and 44 + BPF_JMP32), the 8-bit 'opcode' field is divided into three parts: 43 45 44 - Still, the semantics of the original 32-bit ALU operations are preserved 45 - via 32-bit subregisters. All eBPF registers are 64-bit with 32-bit lower 46 - subregisters that zero-extend into 64-bit if they are being written to. 47 - That behavior maps directly to x86_64 and arm64 subregister definition, but 48 - makes other JITs more difficult. 46 + ============== ====== ================= 47 + 4 bits (MSB) 1 bit 3 bits (LSB) 48 + ============== ====== ================= 49 + operation code source instruction class 50 + ============== ====== ================= 49 51 50 - 32-bit architectures run 64-bit eBPF programs via interpreter. 51 - Their JITs may convert BPF programs that only use 32-bit subregisters into 52 - native instruction set and let the rest being interpreted. 52 + The 4th bit encodes the source operand: 53 53 54 - Operation is 64-bit, because on 64-bit architectures, pointers are also 55 - 64-bit wide, and we want to pass 64-bit values in/out of kernel functions, 56 - so 32-bit eBPF registers would otherwise require to define register-pair 57 - ABI, thus, there won't be able to use a direct eBPF register to HW register 58 - mapping and JIT would need to do combine/split/move operations for every 59 - register in and out of the function, which is complex, bug prone and slow. 60 - Another reason is the use of atomic 64-bit counters. 54 + ====== ===== ======================================== 55 + source value description 56 + ====== ===== ======================================== 57 + BPF_K 0x00 use 32-bit immediate as source operand 58 + BPF_X 0x08 use 'src_reg' register as source operand 59 + ====== ===== ======================================== 61 60 62 - - Conditional jt/jf targets replaced with jt/fall-through: 61 + The four MSB bits store the operation code. 63 62 64 - While the original design has constructs such as ``if (cond) jump_true; 65 - else jump_false;``, they are being replaced into alternative constructs like 66 - ``if (cond) jump_true; /* else fall-through */``. 63 + For class BPF_ALU or BPF_ALU64: 67 64 68 - - Introduces bpf_call insn and register passing convention for zero overhead 69 - calls from/to other kernel functions: 70 - 71 - Before an in-kernel function call, the eBPF program needs to 72 - place function arguments into R1 to R5 registers to satisfy calling 73 - convention, then the interpreter will take them from registers and pass 74 - to in-kernel function. If R1 - R5 registers are mapped to CPU registers 75 - that are used for argument passing on given architecture, the JIT compiler 76 - doesn't need to emit extra moves. Function arguments will be in the correct 77 - registers and BPF_CALL instruction will be JITed as single 'call' HW 78 - instruction. This calling convention was picked to cover common call 79 - situations without performance penalty. 80 - 81 - After an in-kernel function call, R1 - R5 are reset to unreadable and R0 has 82 - a return value of the function. Since R6 - R9 are callee saved, their state 83 - is preserved across the call. 84 - 85 - For example, consider three C functions:: 86 - 87 - u64 f1() { return (*_f2)(1); } 88 - u64 f2(u64 a) { return f3(a + 1, a); } 89 - u64 f3(u64 a, u64 b) { return a - b; } 90 - 91 - GCC can compile f1, f3 into x86_64:: 92 - 93 - f1: 94 - movl $1, %edi 95 - movq _f2(%rip), %rax 96 - jmp *%rax 97 - f3: 98 - movq %rdi, %rax 99 - subq %rsi, %rax 100 - ret 101 - 102 - Function f2 in eBPF may look like:: 103 - 104 - f2: 105 - bpf_mov R2, R1 106 - bpf_add R1, 1 107 - bpf_call f3 108 - bpf_exit 109 - 110 - If f2 is JITed and the pointer stored to ``_f2``. The calls f1 -> f2 -> f3 and 111 - returns will be seamless. Without JIT, __bpf_prog_run() interpreter needs to 112 - be used to call into f2. 113 - 114 - For practical reasons all eBPF programs have only one argument 'ctx' which is 115 - already placed into R1 (e.g. on __bpf_prog_run() startup) and the programs 116 - can call kernel functions with up to 5 arguments. Calls with 6 or more arguments 117 - are currently not supported, but these restrictions can be lifted if necessary 118 - in the future. 119 - 120 - On 64-bit architectures all register map to HW registers one to one. For 121 - example, x86_64 JIT compiler can map them as ... 122 - 123 - :: 124 - 125 - R0 - rax 126 - R1 - rdi 127 - R2 - rsi 128 - R3 - rdx 129 - R4 - rcx 130 - R5 - r8 131 - R6 - rbx 132 - R7 - r13 133 - R8 - r14 134 - R9 - r15 135 - R10 - rbp 136 - 137 - ... since x86_64 ABI mandates rdi, rsi, rdx, rcx, r8, r9 for argument passing 138 - and rbx, r12 - r15 are callee saved. 139 - 140 - Then the following eBPF pseudo-program:: 141 - 142 - bpf_mov R6, R1 /* save ctx */ 143 - bpf_mov R2, 2 144 - bpf_mov R3, 3 145 - bpf_mov R4, 4 146 - bpf_mov R5, 5 147 - bpf_call foo 148 - bpf_mov R7, R0 /* save foo() return value */ 149 - bpf_mov R1, R6 /* restore ctx for next call */ 150 - bpf_mov R2, 6 151 - bpf_mov R3, 7 152 - bpf_mov R4, 8 153 - bpf_mov R5, 9 154 - bpf_call bar 155 - bpf_add R0, R7 156 - bpf_exit 157 - 158 - After JIT to x86_64 may look like:: 159 - 160 - push %rbp 161 - mov %rsp,%rbp 162 - sub $0x228,%rsp 163 - mov %rbx,-0x228(%rbp) 164 - mov %r13,-0x220(%rbp) 165 - mov %rdi,%rbx 166 - mov $0x2,%esi 167 - mov $0x3,%edx 168 - mov $0x4,%ecx 169 - mov $0x5,%r8d 170 - callq foo 171 - mov %rax,%r13 172 - mov %rbx,%rdi 173 - mov $0x6,%esi 174 - mov $0x7,%edx 175 - mov $0x8,%ecx 176 - mov $0x9,%r8d 177 - callq bar 178 - add %r13,%rax 179 - mov -0x228(%rbp),%rbx 180 - mov -0x220(%rbp),%r13 181 - leaveq 182 - retq 183 - 184 - Which is in this example equivalent in C to:: 185 - 186 - u64 bpf_filter(u64 ctx) 187 - { 188 - return foo(ctx, 2, 3, 4, 5) + bar(ctx, 6, 7, 8, 9); 189 - } 190 - 191 - In-kernel functions foo() and bar() with prototype: u64 (*)(u64 arg1, u64 192 - arg2, u64 arg3, u64 arg4, u64 arg5); will receive arguments in proper 193 - registers and place their return value into ``%rax`` which is R0 in eBPF. 194 - Prologue and epilogue are emitted by JIT and are implicit in the 195 - interpreter. R0-R5 are scratch registers, so eBPF program needs to preserve 196 - them across the calls as defined by calling convention. 197 - 198 - For example the following program is invalid:: 199 - 200 - bpf_mov R1, 1 201 - bpf_call foo 202 - bpf_mov R0, R1 203 - bpf_exit 204 - 205 - After the call the registers R1-R5 contain junk values and cannot be read. 206 - An in-kernel `eBPF verifier`_ is used to validate eBPF programs. 207 - 208 - Also in the new design, eBPF is limited to 4096 insns, which means that any 209 - program will terminate quickly and will only call a fixed number of kernel 210 - functions. Original BPF and eBPF are two operand instructions, 211 - which helps to do one-to-one mapping between eBPF insn and x86 insn during JIT. 212 - 213 - The input context pointer for invoking the interpreter function is generic, 214 - its content is defined by a specific use case. For seccomp register R1 points 215 - to seccomp_data, for converted BPF filters R1 points to a skb. 216 - 217 - A program, that is translated internally consists of the following elements:: 218 - 219 - op:16, jt:8, jf:8, k:32 ==> op:8, dst_reg:4, src_reg:4, off:16, imm:32 220 - 221 - So far 87 eBPF instructions were implemented. 8-bit 'op' opcode field 222 - has room for new instructions. Some of them may use 16/24/32 byte encoding. New 223 - instructions must be multiple of 8 bytes to preserve backward compatibility. 224 - 225 - eBPF is a general purpose RISC instruction set. Not every register and 226 - every instruction are used during translation from original BPF to eBPF. 227 - For example, socket filters are not using ``exclusive add`` instruction, but 228 - tracing filters may do to maintain counters of events, for example. Register R9 229 - is not used by socket filters either, but more complex filters may be running 230 - out of registers and would have to resort to spill/fill to stack. 231 - 232 - eBPF can be used as a generic assembler for last step performance 233 - optimizations, socket filters and seccomp are using it as assembler. Tracing 234 - filters may use it as assembler to generate code from kernel. In kernel usage 235 - may not be bounded by security considerations, since generated eBPF code 236 - may be optimizing internal code path and not being exposed to the user space. 237 - Safety of eBPF can come from the `eBPF verifier`_. In such use cases as 238 - described, it may be used as safe instruction set. 239 - 240 - Just like the original BPF, eBPF runs within a controlled environment, 241 - is deterministic and the kernel can easily prove that. The safety of the program 242 - can be determined in two steps: first step does depth-first-search to disallow 243 - loops and other CFG validation; second step starts from the first insn and 244 - descends all possible paths. It simulates execution of every insn and observes 245 - the state change of registers and stack. 246 - 247 - eBPF opcode encoding 248 - ==================== 249 - 250 - eBPF is reusing most of the opcode encoding from classic to simplify conversion 251 - of classic BPF to eBPF. For arithmetic and jump instructions the 8-bit 'code' 252 - field is divided into three parts:: 253 - 254 - +----------------+--------+--------------------+ 255 - | 4 bits | 1 bit | 3 bits | 256 - | operation code | source | instruction class | 257 - +----------------+--------+--------------------+ 258 - (MSB) (LSB) 259 - 260 - Three LSB bits store instruction class which is one of: 261 - 262 - =================== =============== 263 - Classic BPF classes eBPF classes 264 - =================== =============== 265 - BPF_LD 0x00 BPF_LD 0x00 266 - BPF_LDX 0x01 BPF_LDX 0x01 267 - BPF_ST 0x02 BPF_ST 0x02 268 - BPF_STX 0x03 BPF_STX 0x03 269 - BPF_ALU 0x04 BPF_ALU 0x04 270 - BPF_JMP 0x05 BPF_JMP 0x05 271 - BPF_RET 0x06 BPF_JMP32 0x06 272 - BPF_MISC 0x07 BPF_ALU64 0x07 273 - =================== =============== 274 - 275 - When BPF_CLASS(code) == BPF_ALU or BPF_JMP, 4th bit encodes source operand ... 276 - 277 - :: 278 - 279 - BPF_K 0x00 280 - BPF_X 0x08 281 - 282 - * in classic BPF, this means:: 283 - 284 - BPF_SRC(code) == BPF_X - use register X as source operand 285 - BPF_SRC(code) == BPF_K - use 32-bit immediate as source operand 286 - 287 - * in eBPF, this means:: 288 - 289 - BPF_SRC(code) == BPF_X - use 'src_reg' register as source operand 290 - BPF_SRC(code) == BPF_K - use 32-bit immediate as source operand 291 - 292 - ... and four MSB bits store operation code. 293 - 294 - If BPF_CLASS(code) == BPF_ALU or BPF_ALU64 [ in eBPF ], BPF_OP(code) is one of:: 295 - 65 + ======== ===== ========================= 66 + code value description 67 + ======== ===== ========================= 296 68 BPF_ADD 0x00 297 69 BPF_SUB 0x10 298 70 BPF_MUL 0x20 ··· 76 304 BPF_NEG 0x80 77 305 BPF_MOD 0x90 78 306 BPF_XOR 0xa0 79 - BPF_MOV 0xb0 /* eBPF only: mov reg to reg */ 80 - BPF_ARSH 0xc0 /* eBPF only: sign extending shift right */ 81 - BPF_END 0xd0 /* eBPF only: endianness conversion */ 307 + BPF_MOV 0xb0 mov reg to reg 308 + BPF_ARSH 0xc0 sign extending shift right 309 + BPF_END 0xd0 endianness conversion 310 + ======== ===== ========================= 82 311 83 - If BPF_CLASS(code) == BPF_JMP or BPF_JMP32 [ in eBPF ], BPF_OP(code) is one of:: 312 + For class BPF_JMP or BPF_JMP32: 84 313 85 - BPF_JA 0x00 /* BPF_JMP only */ 314 + ======== ===== ========================= 315 + code value description 316 + ======== ===== ========================= 317 + BPF_JA 0x00 BPF_JMP only 86 318 BPF_JEQ 0x10 87 319 BPF_JGT 0x20 88 320 BPF_JGE 0x30 89 321 BPF_JSET 0x40 90 - BPF_JNE 0x50 /* eBPF only: jump != */ 91 - BPF_JSGT 0x60 /* eBPF only: signed '>' */ 92 - BPF_JSGE 0x70 /* eBPF only: signed '>=' */ 93 - BPF_CALL 0x80 /* eBPF BPF_JMP only: function call */ 94 - BPF_EXIT 0x90 /* eBPF BPF_JMP only: function return */ 95 - BPF_JLT 0xa0 /* eBPF only: unsigned '<' */ 96 - BPF_JLE 0xb0 /* eBPF only: unsigned '<=' */ 97 - BPF_JSLT 0xc0 /* eBPF only: signed '<' */ 98 - BPF_JSLE 0xd0 /* eBPF only: signed '<=' */ 322 + BPF_JNE 0x50 jump '!=' 323 + BPF_JSGT 0x60 signed '>' 324 + BPF_JSGE 0x70 signed '>=' 325 + BPF_CALL 0x80 function call 326 + BPF_EXIT 0x90 function return 327 + BPF_JLT 0xa0 unsigned '<' 328 + BPF_JLE 0xb0 unsigned '<=' 329 + BPF_JSLT 0xc0 signed '<' 330 + BPF_JSLE 0xd0 signed '<=' 331 + ======== ===== ========================= 99 332 100 - So BPF_ADD | BPF_X | BPF_ALU means 32-bit addition in both classic BPF 101 - and eBPF. There are only two registers in classic BPF, so it means A += X. 102 - In eBPF it means dst_reg = (u32) dst_reg + (u32) src_reg; similarly, 103 - BPF_XOR | BPF_K | BPF_ALU means A ^= imm32 in classic BPF and analogous 104 - src_reg = (u32) src_reg ^ (u32) imm32 in eBPF. 333 + So BPF_ADD | BPF_X | BPF_ALU means:: 105 334 106 - Classic BPF is using BPF_MISC class to represent A = X and X = A moves. 107 - eBPF is using BPF_MOV | BPF_X | BPF_ALU code instead. Since there are no 108 - BPF_MISC operations in eBPF, the class 7 is used as BPF_ALU64 to mean 109 - exactly the same operations as BPF_ALU, but with 64-bit wide operands 110 - instead. So BPF_ADD | BPF_X | BPF_ALU64 means 64-bit addition, i.e.: 111 - dst_reg = dst_reg + src_reg 335 + dst_reg = (u32) dst_reg + (u32) src_reg; 112 336 113 - Classic BPF wastes the whole BPF_RET class to represent a single ``ret`` 114 - operation. Classic BPF_RET | BPF_K means copy imm32 into return register 115 - and perform function exit. eBPF is modeled to match CPU, so BPF_JMP | BPF_EXIT 116 - in eBPF means function exit only. The eBPF program needs to store return 117 - value into register R0 before doing a BPF_EXIT. Class 6 in eBPF is used as 337 + Similarly, BPF_XOR | BPF_K | BPF_ALU means:: 338 + 339 + src_reg = (u32) src_reg ^ (u32) imm32 340 + 341 + eBPF is using BPF_MOV | BPF_X | BPF_ALU to represent A = B moves. BPF_ALU64 342 + is used to mean exactly the same operations as BPF_ALU, but with 64-bit wide 343 + operands instead. So BPF_ADD | BPF_X | BPF_ALU64 means 64-bit addition, i.e.:: 344 + 345 + dst_reg = dst_reg + src_reg 346 + 347 + BPF_JMP | BPF_EXIT means function exit only. The eBPF program needs to store 348 + the return value into register R0 before doing a BPF_EXIT. Class 6 is used as 118 349 BPF_JMP32 to mean exactly the same operations as BPF_JMP, but with 32-bit wide 119 350 operands for the comparisons instead. 120 351 121 - For load and store instructions the 8-bit 'code' field is divided as:: 122 352 123 - +--------+--------+-------------------+ 124 - | 3 bits | 2 bits | 3 bits | 125 - | mode | size | instruction class | 126 - +--------+--------+-------------------+ 127 - (MSB) (LSB) 353 + Load and store instructions 354 + =========================== 128 355 129 - Size modifier is one of ... 356 + For load and store instructions (BPF_LD, BPF_LDX, BPF_ST and BPF_STX), the 357 + 8-bit 'opcode' field is divided as: 130 358 131 - :: 359 + ============ ====== ================= 360 + 3 bits (MSB) 2 bits 3 bits (LSB) 361 + ============ ====== ================= 362 + mode size instruction class 363 + ============ ====== ================= 132 364 133 - BPF_W 0x00 /* word */ 134 - BPF_H 0x08 /* half word */ 135 - BPF_B 0x10 /* byte */ 136 - BPF_DW 0x18 /* eBPF only, double word */ 365 + The size modifier is one of: 137 366 138 - ... which encodes size of load/store operation:: 367 + ============= ===== ===================== 368 + size modifier value description 369 + ============= ===== ===================== 370 + BPF_W 0x00 word (4 bytes) 371 + BPF_H 0x08 half word (2 bytes) 372 + BPF_B 0x10 byte 373 + BPF_DW 0x18 double word (8 bytes) 374 + ============= ===== ===================== 139 375 140 - B - 1 byte 141 - H - 2 byte 142 - W - 4 byte 143 - DW - 8 byte (eBPF only) 376 + The mode modifier is one of: 144 377 145 - Mode modifier is one of:: 378 + ============= ===== ===================== 379 + mode modifier value description 380 + ============= ===== ===================== 381 + BPF_IMM 0x00 used for 64-bit mov 382 + BPF_ABS 0x20 383 + BPF_IND 0x40 384 + BPF_MEM 0x60 385 + BPF_ATOMIC 0xc0 atomic operations 386 + ============= ===== ===================== 146 387 147 - BPF_IMM 0x00 /* used for 32-bit mov in classic BPF and 64-bit in eBPF */ 148 - BPF_ABS 0x20 149 - BPF_IND 0x40 150 - BPF_MEM 0x60 151 - BPF_LEN 0x80 /* classic BPF only, reserved in eBPF */ 152 - BPF_MSH 0xa0 /* classic BPF only, reserved in eBPF */ 153 - BPF_ATOMIC 0xc0 /* eBPF only, atomic operations */ 388 + BPF_MEM | <size> | BPF_STX means:: 154 389 155 - eBPF has two non-generic instructions: (BPF_ABS | <size> | BPF_LD) and 156 - (BPF_IND | <size> | BPF_LD) which are used to access packet data. 390 + *(size *) (dst_reg + off) = src_reg 157 391 158 - They had to be carried over from classic to have strong performance of 159 - socket filters running in eBPF interpreter. These instructions can only 160 - be used when interpreter context is a pointer to ``struct sk_buff`` and 161 - have seven implicit operands. Register R6 is an implicit input that must 162 - contain pointer to sk_buff. Register R0 is an implicit output which contains 163 - the data fetched from the packet. Registers R1-R5 are scratch registers 164 - and must not be used to store the data across BPF_ABS | BPF_LD or 165 - BPF_IND | BPF_LD instructions. 392 + BPF_MEM | <size> | BPF_ST means:: 166 393 167 - These instructions have implicit program exit condition as well. When 168 - eBPF program is trying to access the data beyond the packet boundary, 169 - the interpreter will abort the execution of the program. JIT compilers 170 - therefore must preserve this property. src_reg and imm32 fields are 171 - explicit inputs to these instructions. 394 + *(size *) (dst_reg + off) = imm32 172 395 173 - For example:: 396 + BPF_MEM | <size> | BPF_LDX means:: 174 397 175 - BPF_IND | BPF_W | BPF_LD means: 176 - 177 - R0 = ntohl(*(u32 *) (((struct sk_buff *) R6)->data + src_reg + imm32)) 178 - and R1 - R5 were scratched. 179 - 180 - Unlike classic BPF instruction set, eBPF has generic load/store operations:: 181 - 182 - BPF_MEM | <size> | BPF_STX: *(size *) (dst_reg + off) = src_reg 183 - BPF_MEM | <size> | BPF_ST: *(size *) (dst_reg + off) = imm32 184 - BPF_MEM | <size> | BPF_LDX: dst_reg = *(size *) (src_reg + off) 398 + dst_reg = *(size *) (src_reg + off) 185 399 186 400 Where size is one of: BPF_B or BPF_H or BPF_W or BPF_DW. 187 401 188 - It also includes atomic operations, which use the immediate field for extra 402 + Atomic operations 403 + ----------------- 404 + 405 + eBPF includes atomic operations, which use the immediate field for extra 189 406 encoding:: 190 407 191 408 .imm = BPF_ADD, .code = BPF_ATOMIC | BPF_W | BPF_STX: lock xadd *(u32 *)(dst_reg + off16) += src_reg ··· 218 457 referring to the exclusive-add operation encoded when the immediate field is 219 458 zero. 220 459 460 + 16-byte instructions 461 + -------------------- 462 + 221 463 eBPF has one 16-byte instruction: ``BPF_LD | BPF_DW | BPF_IMM`` which consists 222 464 of two consecutive ``struct bpf_insn`` 8-byte blocks and interpreted as single 223 465 instruction that loads 64-bit immediate value into a dst_reg. 224 - Classic BPF has similar instruction: ``BPF_LD | BPF_W | BPF_IMM`` which loads 225 - 32-bit immediate value into a register. 226 466 227 - .. Links: 228 - .. _eBPF verifier: verifiers.rst 467 + Packet access instructions 468 + -------------------------- 469 + 470 + eBPF has two non-generic instructions: (BPF_ABS | <size> | BPF_LD) and 471 + (BPF_IND | <size> | BPF_LD) which are used to access packet data. 472 + 473 + They had to be carried over from classic BPF to have strong performance of 474 + socket filters running in eBPF interpreter. These instructions can only 475 + be used when interpreter context is a pointer to ``struct sk_buff`` and 476 + have seven implicit operands. Register R6 is an implicit input that must 477 + contain pointer to sk_buff. Register R0 is an implicit output which contains 478 + the data fetched from the packet. Registers R1-R5 are scratch registers 479 + and must not be used to store the data across BPF_ABS | BPF_LD or 480 + BPF_IND | BPF_LD instructions. 481 + 482 + These instructions have implicit program exit condition as well. When 483 + eBPF program is trying to access the data beyond the packet boundary, 484 + the interpreter will abort the execution of the program. JIT compilers 485 + therefore must preserve this property. src_reg and imm32 fields are 486 + explicit inputs to these instructions. 487 + 488 + For example, BPF_IND | BPF_W | BPF_LD means:: 489 + 490 + R0 = ntohl(*(u32 *) (((struct sk_buff *) R6)->data + src_reg + imm32)) 491 + 492 + and R1 - R5 are clobbered.
+1
arch/s390/mm/hugetlbpage.c
··· 9 9 #define KMSG_COMPONENT "hugetlb" 10 10 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 11 11 12 + #include <asm/pgalloc.h> 12 13 #include <linux/mm.h> 13 14 #include <linux/hugetlb.h> 14 15 #include <linux/mman.h>
+41 -14
arch/x86/net/bpf_jit_comp.c
··· 1976 1976 void *orig_call) 1977 1977 { 1978 1978 int ret, i, nr_args = m->nr_args; 1979 - int stack_size = nr_args * 8; 1979 + int regs_off, ip_off, args_off, stack_size = nr_args * 8; 1980 1980 struct bpf_tramp_progs *fentry = &tprogs[BPF_TRAMP_FENTRY]; 1981 1981 struct bpf_tramp_progs *fexit = &tprogs[BPF_TRAMP_FEXIT]; 1982 1982 struct bpf_tramp_progs *fmod_ret = &tprogs[BPF_TRAMP_MODIFY_RETURN]; ··· 1991 1991 if (!is_valid_bpf_tramp_flags(flags)) 1992 1992 return -EINVAL; 1993 1993 1994 + /* Generated trampoline stack layout: 1995 + * 1996 + * RBP + 8 [ return address ] 1997 + * RBP + 0 [ RBP ] 1998 + * 1999 + * RBP - 8 [ return value ] BPF_TRAMP_F_CALL_ORIG or 2000 + * BPF_TRAMP_F_RET_FENTRY_RET flags 2001 + * 2002 + * [ reg_argN ] always 2003 + * [ ... ] 2004 + * RBP - regs_off [ reg_arg1 ] program's ctx pointer 2005 + * 2006 + * RBP - args_off [ args count ] always 2007 + * 2008 + * RBP - ip_off [ traced function ] BPF_TRAMP_F_IP_ARG flag 2009 + */ 2010 + 1994 2011 /* room for return value of orig_call or fentry prog */ 1995 2012 save_ret = flags & (BPF_TRAMP_F_CALL_ORIG | BPF_TRAMP_F_RET_FENTRY_RET); 1996 2013 if (save_ret) 1997 2014 stack_size += 8; 1998 2015 2016 + regs_off = stack_size; 2017 + 2018 + /* args count */ 2019 + stack_size += 8; 2020 + args_off = stack_size; 2021 + 1999 2022 if (flags & BPF_TRAMP_F_IP_ARG) 2000 2023 stack_size += 8; /* room for IP address argument */ 2024 + 2025 + ip_off = stack_size; 2001 2026 2002 2027 if (flags & BPF_TRAMP_F_SKIP_FRAME) 2003 2028 /* skip patched call instruction and point orig_call to actual ··· 2037 2012 EMIT4(0x48, 0x83, 0xEC, stack_size); /* sub rsp, stack_size */ 2038 2013 EMIT1(0x53); /* push rbx */ 2039 2014 2015 + /* Store number of arguments of the traced function: 2016 + * mov rax, nr_args 2017 + * mov QWORD PTR [rbp - args_off], rax 2018 + */ 2019 + emit_mov_imm64(&prog, BPF_REG_0, 0, (u32) nr_args); 2020 + emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -args_off); 2021 + 2040 2022 if (flags & BPF_TRAMP_F_IP_ARG) { 2041 2023 /* Store IP address of the traced function: 2042 2024 * mov rax, QWORD PTR [rbp + 8] 2043 2025 * sub rax, X86_PATCH_SIZE 2044 - * mov QWORD PTR [rbp - stack_size], rax 2026 + * mov QWORD PTR [rbp - ip_off], rax 2045 2027 */ 2046 2028 emit_ldx(&prog, BPF_DW, BPF_REG_0, BPF_REG_FP, 8); 2047 2029 EMIT4(0x48, 0x83, 0xe8, X86_PATCH_SIZE); 2048 - emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -stack_size); 2049 - 2050 - /* Continue with stack_size for regs storage, stack will 2051 - * be correctly restored with 'leave' instruction. 2052 - */ 2053 - stack_size -= 8; 2030 + emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -ip_off); 2054 2031 } 2055 2032 2056 - save_regs(m, &prog, nr_args, stack_size); 2033 + save_regs(m, &prog, nr_args, regs_off); 2057 2034 2058 2035 if (flags & BPF_TRAMP_F_CALL_ORIG) { 2059 2036 /* arg1: mov rdi, im */ ··· 2067 2040 } 2068 2041 2069 2042 if (fentry->nr_progs) 2070 - if (invoke_bpf(m, &prog, fentry, stack_size, 2043 + if (invoke_bpf(m, &prog, fentry, regs_off, 2071 2044 flags & BPF_TRAMP_F_RET_FENTRY_RET)) 2072 2045 return -EINVAL; 2073 2046 ··· 2077 2050 if (!branches) 2078 2051 return -ENOMEM; 2079 2052 2080 - if (invoke_bpf_mod_ret(m, &prog, fmod_ret, stack_size, 2053 + if (invoke_bpf_mod_ret(m, &prog, fmod_ret, regs_off, 2081 2054 branches)) { 2082 2055 ret = -EINVAL; 2083 2056 goto cleanup; ··· 2085 2058 } 2086 2059 2087 2060 if (flags & BPF_TRAMP_F_CALL_ORIG) { 2088 - restore_regs(m, &prog, nr_args, stack_size); 2061 + restore_regs(m, &prog, nr_args, regs_off); 2089 2062 2090 2063 /* call original function */ 2091 2064 if (emit_call(&prog, orig_call, prog)) { ··· 2115 2088 } 2116 2089 2117 2090 if (fexit->nr_progs) 2118 - if (invoke_bpf(m, &prog, fexit, stack_size, false)) { 2091 + if (invoke_bpf(m, &prog, fexit, regs_off, false)) { 2119 2092 ret = -EINVAL; 2120 2093 goto cleanup; 2121 2094 } 2122 2095 2123 2096 if (flags & BPF_TRAMP_F_RESTORE_REGS) 2124 - restore_regs(m, &prog, nr_args, stack_size); 2097 + restore_regs(m, &prog, nr_args, regs_off); 2125 2098 2126 2099 /* This needs to be done regardless. If there were fmod_ret programs, 2127 2100 * the return value is only updated on the stack and still needs to be
+1
drivers/bluetooth/btqca.c
··· 6 6 */ 7 7 #include <linux/module.h> 8 8 #include <linux/firmware.h> 9 + #include <linux/vmalloc.h> 9 10 10 11 #include <net/bluetooth/bluetooth.h> 11 12 #include <net/bluetooth/hci_core.h>
+1
drivers/infiniband/core/cache.c
··· 33 33 * SOFTWARE. 34 34 */ 35 35 36 + #include <linux/if_vlan.h> 36 37 #include <linux/module.h> 37 38 #include <linux/errno.h> 38 39 #include <linux/slab.h>
+2
drivers/infiniband/hw/irdma/ctrl.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB 2 2 /* Copyright (c) 2015 - 2021 Intel Corporation */ 3 + #include <linux/etherdevice.h> 4 + 3 5 #include "osdep.h" 4 6 #include "status.h" 5 7 #include "hmc.h"
+2
drivers/infiniband/hw/irdma/uda.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 or Linux-OpenIB 2 2 /* Copyright (c) 2016 - 2021 Intel Corporation */ 3 + #include <linux/etherdevice.h> 4 + 3 5 #include "osdep.h" 4 6 #include "status.h" 5 7 #include "hmc.h"
+1
drivers/infiniband/hw/mlx5/doorbell.c
··· 32 32 33 33 #include <linux/kref.h> 34 34 #include <linux/slab.h> 35 + #include <linux/sched/mm.h> 35 36 #include <rdma/ib_umem.h> 36 37 37 38 #include "mlx5_ib.h"
+1
drivers/infiniband/hw/mlx5/qp.c
··· 30 30 * SOFTWARE. 31 31 */ 32 32 33 + #include <linux/etherdevice.h> 33 34 #include <linux/module.h> 34 35 #include <rdma/ib_umem.h> 35 36 #include <rdma/ib_cache.h>
+1
drivers/net/amt.c
··· 11 11 #include <linux/net.h> 12 12 #include <linux/igmp.h> 13 13 #include <linux/workqueue.h> 14 + #include <net/sch_generic.h> 14 15 #include <net/net_namespace.h> 15 16 #include <net/ip.h> 16 17 #include <net/udp.h>
+1
drivers/net/appletalk/ipddp.c
··· 23 23 * of the GNU General Public License, incorporated herein by reference. 24 24 */ 25 25 26 + #include <linux/compat.h> 26 27 #include <linux/module.h> 27 28 #include <linux/kernel.h> 28 29 #include <linux/init.h>
+1
drivers/net/bonding/bond_main.c
··· 35 35 #include <linux/module.h> 36 36 #include <linux/types.h> 37 37 #include <linux/fcntl.h> 38 + #include <linux/filter.h> 38 39 #include <linux/interrupt.h> 39 40 #include <linux/ptrace.h> 40 41 #include <linux/ioport.h>
+1
drivers/net/can/usb/peak_usb/pcan_usb.c
··· 8 8 * 9 9 * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de> 10 10 */ 11 + #include <asm/unaligned.h> 11 12 #include <linux/netdevice.h> 12 13 #include <linux/usb.h> 13 14 #include <linux/module.h>
+1
drivers/net/dsa/microchip/ksz8795.c
··· 10 10 #include <linux/delay.h> 11 11 #include <linux/export.h> 12 12 #include <linux/gpio.h> 13 + #include <linux/if_vlan.h> 13 14 #include <linux/kernel.h> 14 15 #include <linux/module.h> 15 16 #include <linux/platform_data/microchip-ksz.h>
+1
drivers/net/dsa/xrs700x/xrs700x.c
··· 5 5 */ 6 6 7 7 #include <net/dsa.h> 8 + #include <linux/etherdevice.h> 8 9 #include <linux/if_bridge.h> 9 10 #include <linux/of_device.h> 10 11 #include <linux/netdev_features.h>
+1 -1
drivers/net/ethernet/amazon/ena/ena_netdev.c
··· 434 434 xdp_stat = &rx_ring->rx_stats.xdp_pass; 435 435 break; 436 436 default: 437 - bpf_warn_invalid_xdp_action(verdict); 437 + bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, verdict); 438 438 xdp_stat = &rx_ring->rx_stats.xdp_invalid; 439 439 } 440 440
+1
drivers/net/ethernet/amazon/ena/ena_netdev.h
··· 14 14 #include <linux/interrupt.h> 15 15 #include <linux/netdevice.h> 16 16 #include <linux/skbuff.h> 17 + #include <uapi/linux/bpf.h> 17 18 18 19 #include "ena_com.h" 19 20 #include "ena_eth_com.h"
+1
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
··· 9 9 10 10 #include <linux/pci.h> 11 11 #include <linux/netdevice.h> 12 + #include <linux/vmalloc.h> 12 13 #include <net/devlink.h> 13 14 #include "bnxt_hsi.h" 14 15 #include "bnxt.h"
+1 -1
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
··· 195 195 *event |= BNXT_REDIRECT_EVENT; 196 196 break; 197 197 default: 198 - bpf_warn_invalid_xdp_action(act); 198 + bpf_warn_invalid_xdp_action(bp->dev, xdp_prog, act); 199 199 fallthrough; 200 200 case XDP_ABORTED: 201 201 trace_xdp_exception(bp->dev, xdp_prog, act);
+1 -1
drivers/net/ethernet/cavium/thunder/nicvf_main.c
··· 590 590 nicvf_xdp_sq_append_pkt(nic, sq, (u64)xdp.data, dma_addr, len); 591 591 return true; 592 592 default: 593 - bpf_warn_invalid_xdp_action(action); 593 + bpf_warn_invalid_xdp_action(nic->netdev, prog, action); 594 594 fallthrough; 595 595 case XDP_ABORTED: 596 596 trace_xdp_exception(nic->netdev, prog, action);
+1
drivers/net/ethernet/cavium/thunder/nicvf_queues.c
··· 10 10 #include <linux/iommu.h> 11 11 #include <net/ip.h> 12 12 #include <net/tso.h> 13 + #include <uapi/linux/bpf.h> 13 14 14 15 #include "nic_reg.h" 15 16 #include "nic.h"
+1 -1
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
··· 2623 2623 } 2624 2624 break; 2625 2625 default: 2626 - bpf_warn_invalid_xdp_action(xdp_act); 2626 + bpf_warn_invalid_xdp_action(priv->net_dev, xdp_prog, xdp_act); 2627 2627 fallthrough; 2628 2628 case XDP_ABORTED: 2629 2629 trace_xdp_exception(priv->net_dev, xdp_prog, xdp_act);
+1 -1
drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
··· 374 374 dpaa2_eth_xdp_enqueue(priv, ch, fd, vaddr, rx_fq->flowid); 375 375 break; 376 376 default: 377 - bpf_warn_invalid_xdp_action(xdp_act); 377 + bpf_warn_invalid_xdp_action(priv->net_dev, xdp_prog, xdp_act); 378 378 fallthrough; 379 379 case XDP_ABORTED: 380 380 trace_xdp_exception(priv->net_dev, xdp_prog, xdp_act);
+1 -1
drivers/net/ethernet/freescale/enetc/enetc.c
··· 1547 1547 1548 1548 switch (xdp_act) { 1549 1549 default: 1550 - bpf_warn_invalid_xdp_action(xdp_act); 1550 + bpf_warn_invalid_xdp_action(rx_ring->ndev, prog, xdp_act); 1551 1551 fallthrough; 1552 1552 case XDP_ABORTED: 1553 1553 trace_xdp_exception(rx_ring->ndev, prog, xdp_act);
+1
drivers/net/ethernet/huawei/hinic/hinic_tx.c
··· 4 4 * Copyright(c) 2017 Huawei Technologies Co., Ltd 5 5 */ 6 6 7 + #include <linux/if_vlan.h> 7 8 #include <linux/kernel.h> 8 9 #include <linux/netdevice.h> 9 10 #include <linux/u64_stats_sync.h>
+1 -1
drivers/net/ethernet/intel/i40e/i40e_txrx.c
··· 2322 2322 result = I40E_XDP_REDIR; 2323 2323 break; 2324 2324 default: 2325 - bpf_warn_invalid_xdp_action(act); 2325 + bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, act); 2326 2326 fallthrough; 2327 2327 case XDP_ABORTED: 2328 2328 out_failure:
+1 -1
drivers/net/ethernet/intel/i40e/i40e_xsk.c
··· 176 176 goto out_failure; 177 177 break; 178 178 default: 179 - bpf_warn_invalid_xdp_action(act); 179 + bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, act); 180 180 fallthrough; 181 181 case XDP_ABORTED: 182 182 out_failure:
-1
drivers/net/ethernet/intel/i40e/i40e_xsk.h
··· 22 22 23 23 struct i40e_vsi; 24 24 struct xsk_buff_pool; 25 - struct zero_copy_allocator; 26 25 27 26 int i40e_queue_pair_disable(struct i40e_vsi *vsi, int queue_pair); 28 27 int i40e_queue_pair_enable(struct i40e_vsi *vsi, int queue_pair);
+2
drivers/net/ethernet/intel/ice/ice_devlink.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* Copyright (c) 2020, Intel Corporation. */ 3 3 4 + #include <linux/vmalloc.h> 5 + 4 6 #include "ice.h" 5 7 #include "ice_lib.h" 6 8 #include "ice_devlink.h"
+1 -1
drivers/net/ethernet/intel/ice/ice_txrx.c
··· 576 576 goto out_failure; 577 577 return ICE_XDP_REDIR; 578 578 default: 579 - bpf_warn_invalid_xdp_action(act); 579 + bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, act); 580 580 fallthrough; 581 581 case XDP_ABORTED: 582 582 out_failure:
+2
drivers/net/ethernet/intel/ice/ice_txrx_lib.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* Copyright (c) 2019, Intel Corporation. */ 3 3 4 + #include <linux/filter.h> 5 + 4 6 #include "ice_txrx_lib.h" 5 7 #include "ice_eswitch.h" 6 8 #include "ice_lib.h"
+1 -1
drivers/net/ethernet/intel/ice/ice_xsk.c
··· 481 481 goto out_failure; 482 482 break; 483 483 default: 484 - bpf_warn_invalid_xdp_action(act); 484 + bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, act); 485 485 fallthrough; 486 486 case XDP_ABORTED: 487 487 out_failure:
+1 -1
drivers/net/ethernet/intel/igb/igb_main.c
··· 8500 8500 result = IGB_XDP_REDIR; 8501 8501 break; 8502 8502 default: 8503 - bpf_warn_invalid_xdp_action(act); 8503 + bpf_warn_invalid_xdp_action(adapter->netdev, xdp_prog, act); 8504 8504 fallthrough; 8505 8505 case XDP_ABORTED: 8506 8506 out_failure:
+1 -1
drivers/net/ethernet/intel/igc/igc_main.c
··· 2241 2241 return IGC_XDP_REDIRECT; 2242 2242 break; 2243 2243 default: 2244 - bpf_warn_invalid_xdp_action(act); 2244 + bpf_warn_invalid_xdp_action(adapter->netdev, prog, act); 2245 2245 fallthrough; 2246 2246 case XDP_ABORTED: 2247 2247 out_failure:
+1
drivers/net/ethernet/intel/igc/igc_xdp.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* Copyright (c) 2020, Intel Corporation. */ 3 3 4 + #include <linux/if_vlan.h> 4 5 #include <net/xdp_sock_drv.h> 5 6 6 7 #include "igc.h"
+1 -1
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
··· 2235 2235 result = IXGBE_XDP_REDIR; 2236 2236 break; 2237 2237 default: 2238 - bpf_warn_invalid_xdp_action(act); 2238 + bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, act); 2239 2239 fallthrough; 2240 2240 case XDP_ABORTED: 2241 2241 out_failure:
-2
drivers/net/ethernet/intel/ixgbe/ixgbe_txrx_common.h
··· 35 35 struct xsk_buff_pool *pool, 36 36 u16 qid); 37 37 38 - void ixgbe_zca_free(struct zero_copy_allocator *alloc, unsigned long handle); 39 - 40 38 bool ixgbe_alloc_rx_buffers_zc(struct ixgbe_ring *rx_ring, u16 cleaned_count); 41 39 int ixgbe_clean_rx_irq_zc(struct ixgbe_q_vector *q_vector, 42 40 struct ixgbe_ring *rx_ring,
+1 -1
drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
··· 131 131 goto out_failure; 132 132 break; 133 133 default: 134 - bpf_warn_invalid_xdp_action(act); 134 + bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, act); 135 135 fallthrough; 136 136 case XDP_ABORTED: 137 137 out_failure:
+1 -1
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
··· 1070 1070 goto out_failure; 1071 1071 break; 1072 1072 default: 1073 - bpf_warn_invalid_xdp_action(act); 1073 + bpf_warn_invalid_xdp_action(rx_ring->netdev, xdp_prog, act); 1074 1074 fallthrough; 1075 1075 case XDP_ABORTED: 1076 1076 out_failure:
+1 -1
drivers/net/ethernet/marvell/mvneta.c
··· 2240 2240 mvneta_xdp_put_buff(pp, rxq, xdp, sinfo, sync); 2241 2241 break; 2242 2242 default: 2243 - bpf_warn_invalid_xdp_action(act); 2243 + bpf_warn_invalid_xdp_action(pp->dev, prog, act); 2244 2244 fallthrough; 2245 2245 case XDP_ABORTED: 2246 2246 trace_xdp_exception(pp->dev, prog, act);
+1 -1
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
··· 3823 3823 } 3824 3824 break; 3825 3825 default: 3826 - bpf_warn_invalid_xdp_action(act); 3826 + bpf_warn_invalid_xdp_action(port->dev, prog, act); 3827 3827 fallthrough; 3828 3828 case XDP_ABORTED: 3829 3829 trace_xdp_exception(port->dev, prog, act);
+1 -1
drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
··· 1198 1198 put_page(page); 1199 1199 break; 1200 1200 default: 1201 - bpf_warn_invalid_xdp_action(act); 1201 + bpf_warn_invalid_xdp_action(pfvf->netdev, prog, act); 1202 1202 break; 1203 1203 case XDP_ABORTED: 1204 1204 trace_xdp_exception(pfvf->netdev, prog, act);
+1
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
··· 33 33 34 34 #include <linux/bpf.h> 35 35 #include <linux/etherdevice.h> 36 + #include <linux/filter.h> 36 37 #include <linux/tcp.h> 37 38 #include <linux/if_vlan.h> 38 39 #include <linux/delay.h>
+1 -1
drivers/net/ethernet/mellanox/mlx4/en_rx.c
··· 812 812 trace_xdp_exception(dev, xdp_prog, act); 813 813 goto xdp_drop_no_cnt; /* Drop on xmit failure */ 814 814 default: 815 - bpf_warn_invalid_xdp_action(act); 815 + bpf_warn_invalid_xdp_action(dev, xdp_prog, act); 816 816 fallthrough; 817 817 case XDP_ABORTED: 818 818 trace_xdp_exception(dev, xdp_prog, act);
+1
drivers/net/ethernet/mellanox/mlx5/core/en/qos.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 2 /* Copyright (c) 2020, Mellanox Technologies inc. All rights reserved. */ 3 + #include <net/sch_generic.h> 3 4 4 5 #include "en.h" 5 6 #include "params.h"
+1 -1
drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
··· 151 151 rq->stats->xdp_redirect++; 152 152 return true; 153 153 default: 154 - bpf_warn_invalid_xdp_action(act); 154 + bpf_warn_invalid_xdp_action(rq->netdev, prog, act); 155 155 fallthrough; 156 156 case XDP_ABORTED: 157 157 xdp_abort:
+1 -1
drivers/net/ethernet/microsoft/mana/mana_bpf.c
··· 60 60 break; 61 61 62 62 default: 63 - bpf_warn_invalid_xdp_action(act); 63 + bpf_warn_invalid_xdp_action(ndev, prog, act); 64 64 } 65 65 66 66 out:
+2
drivers/net/ethernet/microsoft/mana/mana_en.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* Copyright (c) 2021, Microsoft Corporation. */ 3 3 4 + #include <uapi/linux/bpf.h> 5 + 4 6 #include <linux/inetdevice.h> 5 7 #include <linux/etherdevice.h> 6 8 #include <linux/ethtool.h>
+1 -1
drivers/net/ethernet/netronome/nfp/nfp_net_common.c
··· 1944 1944 xdp_prog, act); 1945 1945 continue; 1946 1946 default: 1947 - bpf_warn_invalid_xdp_action(act); 1947 + bpf_warn_invalid_xdp_action(dp->netdev, xdp_prog, act); 1948 1948 fallthrough; 1949 1949 case XDP_ABORTED: 1950 1950 trace_xdp_exception(dp->netdev, xdp_prog, act);
+1 -1
drivers/net/ethernet/qlogic/qede/qede_fp.c
··· 1153 1153 qede_rx_bd_ring_consume(rxq); 1154 1154 break; 1155 1155 default: 1156 - bpf_warn_invalid_xdp_action(act); 1156 + bpf_warn_invalid_xdp_action(edev->ndev, prog, act); 1157 1157 fallthrough; 1158 1158 case XDP_ABORTED: 1159 1159 trace_xdp_exception(edev->ndev, prog, act);
+1
drivers/net/ethernet/sfc/efx.c
··· 5 5 * Copyright 2005-2013 Solarflare Communications Inc. 6 6 */ 7 7 8 + #include <linux/filter.h> 8 9 #include <linux/module.h> 9 10 #include <linux/pci.h> 10 11 #include <linux/netdevice.h>
+1
drivers/net/ethernet/sfc/efx_channels.c
··· 10 10 11 11 #include "net_driver.h" 12 12 #include <linux/module.h> 13 + #include <linux/filter.h> 13 14 #include "efx_channels.h" 14 15 #include "efx.h" 15 16 #include "efx_common.h"
+1
drivers/net/ethernet/sfc/efx_common.c
··· 9 9 */ 10 10 11 11 #include "net_driver.h" 12 + #include <linux/filter.h> 12 13 #include <linux/module.h> 13 14 #include <linux/netdevice.h> 14 15 #include <net/gre.h>
+1 -1
drivers/net/ethernet/sfc/rx.c
··· 338 338 break; 339 339 340 340 default: 341 - bpf_warn_invalid_xdp_action(xdp_act); 341 + bpf_warn_invalid_xdp_action(efx->net_dev, xdp_prog, xdp_act); 342 342 efx_free_rx_buffers(rx_queue, rx_buf, 1); 343 343 channel->n_rx_xdp_bad_drops++; 344 344 trace_xdp_exception(efx->net_dev, xdp_prog, xdp_act);
+1 -1
drivers/net/ethernet/socionext/netsec.c
··· 933 933 } 934 934 break; 935 935 default: 936 - bpf_warn_invalid_xdp_action(act); 936 + bpf_warn_invalid_xdp_action(priv->ndev, prog, act); 937 937 fallthrough; 938 938 case XDP_ABORTED: 939 939 trace_xdp_exception(priv->ndev, prog, act);
+1
drivers/net/ethernet/stmicro/stmmac/stmmac.h
··· 22 22 #include <linux/net_tstamp.h> 23 23 #include <linux/reset.h> 24 24 #include <net/page_pool.h> 25 + #include <uapi/linux/bpf.h> 25 26 26 27 struct stmmac_resources { 27 28 void __iomem *addr;
+1 -1
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 4723 4723 res = STMMAC_XDP_REDIRECT; 4724 4724 break; 4725 4725 default: 4726 - bpf_warn_invalid_xdp_action(act); 4726 + bpf_warn_invalid_xdp_action(priv->dev, prog, act); 4727 4727 fallthrough; 4728 4728 case XDP_ABORTED: 4729 4729 trace_xdp_exception(priv->dev, prog, act);
+1 -1
drivers/net/ethernet/ti/cpsw_priv.c
··· 1362 1362 xdp_do_flush_map(); 1363 1363 break; 1364 1364 default: 1365 - bpf_warn_invalid_xdp_action(act); 1365 + bpf_warn_invalid_xdp_action(ndev, prog, act); 1366 1366 fallthrough; 1367 1367 case XDP_ABORTED: 1368 1368 trace_xdp_exception(ndev, prog, act);
+2
drivers/net/ethernet/ti/cpsw_priv.h
··· 6 6 #ifndef DRIVERS_NET_ETHERNET_TI_CPSW_PRIV_H_ 7 7 #define DRIVERS_NET_ETHERNET_TI_CPSW_PRIV_H_ 8 8 9 + #include <uapi/linux/bpf.h> 10 + 9 11 #include "davinci_cpdma.h" 10 12 11 13 #define CPSW_DEBUG (NETIF_MSG_HW | NETIF_MSG_WOL | \
+1
drivers/net/hamradio/hdlcdrv.c
··· 30 30 /*****************************************************************************/ 31 31 32 32 #include <linux/capability.h> 33 + #include <linux/compat.h> 33 34 #include <linux/module.h> 34 35 #include <linux/types.h> 35 36 #include <linux/net.h>
+1
drivers/net/hamradio/scc.c
··· 148 148 149 149 /* ----------------------------------------------------------------------- */ 150 150 151 + #include <linux/compat.h> 151 152 #include <linux/module.h> 152 153 #include <linux/errno.h> 153 154 #include <linux/signal.h>
+1 -1
drivers/net/hyperv/netvsc_bpf.c
··· 68 68 break; 69 69 70 70 default: 71 - bpf_warn_invalid_xdp_action(act); 71 + bpf_warn_invalid_xdp_action(ndev, prog, act); 72 72 } 73 73 74 74 out:
+1
drivers/net/loopback.c
··· 44 44 #include <linux/etherdevice.h> 45 45 #include <linux/skbuff.h> 46 46 #include <linux/ethtool.h> 47 + #include <net/sch_generic.h> 47 48 #include <net/sock.h> 48 49 #include <net/checksum.h> 49 50 #include <linux/if_ether.h> /* For the statistics structure. */
+1 -1
drivers/net/tun.c
··· 1602 1602 case XDP_PASS: 1603 1603 break; 1604 1604 default: 1605 - bpf_warn_invalid_xdp_action(act); 1605 + bpf_warn_invalid_xdp_action(tun->dev, xdp_prog, act); 1606 1606 fallthrough; 1607 1607 case XDP_ABORTED: 1608 1608 trace_xdp_exception(tun->dev, xdp_prog, act);
+2 -2
drivers/net/veth.c
··· 644 644 rcu_read_unlock(); 645 645 goto xdp_xmit; 646 646 default: 647 - bpf_warn_invalid_xdp_action(act); 647 + bpf_warn_invalid_xdp_action(rq->dev, xdp_prog, act); 648 648 fallthrough; 649 649 case XDP_ABORTED: 650 650 trace_xdp_exception(rq->dev, xdp_prog, act); ··· 794 794 rcu_read_unlock(); 795 795 goto xdp_xmit; 796 796 default: 797 - bpf_warn_invalid_xdp_action(act); 797 + bpf_warn_invalid_xdp_action(rq->dev, xdp_prog, act); 798 798 fallthrough; 799 799 case XDP_ABORTED: 800 800 trace_xdp_exception(rq->dev, xdp_prog, act);
+2 -2
drivers/net/virtio_net.c
··· 812 812 rcu_read_unlock(); 813 813 goto xdp_xmit; 814 814 default: 815 - bpf_warn_invalid_xdp_action(act); 815 + bpf_warn_invalid_xdp_action(vi->dev, xdp_prog, act); 816 816 fallthrough; 817 817 case XDP_ABORTED: 818 818 trace_xdp_exception(vi->dev, xdp_prog, act); ··· 1022 1022 rcu_read_unlock(); 1023 1023 goto xdp_xmit; 1024 1024 default: 1025 - bpf_warn_invalid_xdp_action(act); 1025 + bpf_warn_invalid_xdp_action(vi->dev, xdp_prog, act); 1026 1026 fallthrough; 1027 1027 case XDP_ABORTED: 1028 1028 trace_xdp_exception(vi->dev, xdp_prog, act);
+1
drivers/net/vrf.c
··· 34 34 #include <net/addrconf.h> 35 35 #include <net/l3mdev.h> 36 36 #include <net/fib_rules.h> 37 + #include <net/sch_generic.h> 37 38 #include <net/netns/generic.h> 38 39 #include <net/netfilter/nf_conntrack.h> 39 40
+1 -1
drivers/net/xen-netfront.c
··· 948 948 break; 949 949 950 950 default: 951 - bpf_warn_invalid_xdp_action(act); 951 + bpf_warn_invalid_xdp_action(queue->info->netdev, prog, act); 952 952 } 953 953 954 954 return act;
+1
fs/nfs/dir.c
··· 18 18 * 6 Jun 1999 Cache readdir lookups in the page cache. -DaveM 19 19 */ 20 20 21 + #include <linux/compat.h> 21 22 #include <linux/module.h> 22 23 #include <linux/time.h> 23 24 #include <linux/errno.h>
+1
fs/nfs/fs_context.c
··· 10 10 * Split from fs/nfs/super.c by David Howells <dhowells@redhat.com> 11 11 */ 12 12 13 + #include <linux/compat.h> 13 14 #include <linux/module.h> 14 15 #include <linux/fs.h> 15 16 #include <linux/fs_context.h>
+1
fs/select.c
··· 15 15 * of fds to overcome nfds < 16390 descriptors limit (Tigran Aivazian). 16 16 */ 17 17 18 + #include <linux/compat.h> 18 19 #include <linux/kernel.h> 19 20 #include <linux/sched/signal.h> 20 21 #include <linux/sched/rt.h>
+70
include/linux/bpf-cgroup-defs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _BPF_CGROUP_DEFS_H 3 + #define _BPF_CGROUP_DEFS_H 4 + 5 + #ifdef CONFIG_CGROUP_BPF 6 + 7 + #include <linux/list.h> 8 + #include <linux/percpu-refcount.h> 9 + #include <linux/workqueue.h> 10 + 11 + struct bpf_prog_array; 12 + 13 + enum cgroup_bpf_attach_type { 14 + CGROUP_BPF_ATTACH_TYPE_INVALID = -1, 15 + CGROUP_INET_INGRESS = 0, 16 + CGROUP_INET_EGRESS, 17 + CGROUP_INET_SOCK_CREATE, 18 + CGROUP_SOCK_OPS, 19 + CGROUP_DEVICE, 20 + CGROUP_INET4_BIND, 21 + CGROUP_INET6_BIND, 22 + CGROUP_INET4_CONNECT, 23 + CGROUP_INET6_CONNECT, 24 + CGROUP_INET4_POST_BIND, 25 + CGROUP_INET6_POST_BIND, 26 + CGROUP_UDP4_SENDMSG, 27 + CGROUP_UDP6_SENDMSG, 28 + CGROUP_SYSCTL, 29 + CGROUP_UDP4_RECVMSG, 30 + CGROUP_UDP6_RECVMSG, 31 + CGROUP_GETSOCKOPT, 32 + CGROUP_SETSOCKOPT, 33 + CGROUP_INET4_GETPEERNAME, 34 + CGROUP_INET6_GETPEERNAME, 35 + CGROUP_INET4_GETSOCKNAME, 36 + CGROUP_INET6_GETSOCKNAME, 37 + CGROUP_INET_SOCK_RELEASE, 38 + MAX_CGROUP_BPF_ATTACH_TYPE 39 + }; 40 + 41 + struct cgroup_bpf { 42 + /* array of effective progs in this cgroup */ 43 + struct bpf_prog_array __rcu *effective[MAX_CGROUP_BPF_ATTACH_TYPE]; 44 + 45 + /* attached progs to this cgroup and attach flags 46 + * when flags == 0 or BPF_F_ALLOW_OVERRIDE the progs list will 47 + * have either zero or one element 48 + * when BPF_F_ALLOW_MULTI the list can have up to BPF_CGROUP_MAX_PROGS 49 + */ 50 + struct list_head progs[MAX_CGROUP_BPF_ATTACH_TYPE]; 51 + u32 flags[MAX_CGROUP_BPF_ATTACH_TYPE]; 52 + 53 + /* list of cgroup shared storages */ 54 + struct list_head storages; 55 + 56 + /* temp storage for effective prog array used by prog_attach/detach */ 57 + struct bpf_prog_array *inactive; 58 + 59 + /* reference counter used to detach bpf programs after cgroup removal */ 60 + struct percpu_ref refcnt; 61 + 62 + /* cgroup_bpf is released using a work queue */ 63 + struct work_struct release_work; 64 + }; 65 + 66 + #else /* CONFIG_CGROUP_BPF */ 67 + struct cgroup_bpf {}; 68 + #endif /* CONFIG_CGROUP_BPF */ 69 + 70 + #endif
+1 -56
include/linux/bpf-cgroup.h
··· 3 3 #define _BPF_CGROUP_H 4 4 5 5 #include <linux/bpf.h> 6 + #include <linux/bpf-cgroup-defs.h> 6 7 #include <linux/errno.h> 7 8 #include <linux/jump_label.h> 8 9 #include <linux/percpu.h> 9 - #include <linux/percpu-refcount.h> 10 10 #include <linux/rbtree.h> 11 11 #include <uapi/linux/bpf.h> 12 12 ··· 23 23 struct task_struct; 24 24 25 25 #ifdef CONFIG_CGROUP_BPF 26 - enum cgroup_bpf_attach_type { 27 - CGROUP_BPF_ATTACH_TYPE_INVALID = -1, 28 - CGROUP_INET_INGRESS = 0, 29 - CGROUP_INET_EGRESS, 30 - CGROUP_INET_SOCK_CREATE, 31 - CGROUP_SOCK_OPS, 32 - CGROUP_DEVICE, 33 - CGROUP_INET4_BIND, 34 - CGROUP_INET6_BIND, 35 - CGROUP_INET4_CONNECT, 36 - CGROUP_INET6_CONNECT, 37 - CGROUP_INET4_POST_BIND, 38 - CGROUP_INET6_POST_BIND, 39 - CGROUP_UDP4_SENDMSG, 40 - CGROUP_UDP6_SENDMSG, 41 - CGROUP_SYSCTL, 42 - CGROUP_UDP4_RECVMSG, 43 - CGROUP_UDP6_RECVMSG, 44 - CGROUP_GETSOCKOPT, 45 - CGROUP_SETSOCKOPT, 46 - CGROUP_INET4_GETPEERNAME, 47 - CGROUP_INET6_GETPEERNAME, 48 - CGROUP_INET4_GETSOCKNAME, 49 - CGROUP_INET6_GETSOCKNAME, 50 - CGROUP_INET_SOCK_RELEASE, 51 - MAX_CGROUP_BPF_ATTACH_TYPE 52 - }; 53 26 54 27 #define CGROUP_ATYPE(type) \ 55 28 case BPF_##type: return type ··· 98 125 struct bpf_prog *prog; 99 126 struct bpf_cgroup_link *link; 100 127 struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE]; 101 - }; 102 - 103 - struct bpf_prog_array; 104 - 105 - struct cgroup_bpf { 106 - /* array of effective progs in this cgroup */ 107 - struct bpf_prog_array __rcu *effective[MAX_CGROUP_BPF_ATTACH_TYPE]; 108 - 109 - /* attached progs to this cgroup and attach flags 110 - * when flags == 0 or BPF_F_ALLOW_OVERRIDE the progs list will 111 - * have either zero or one element 112 - * when BPF_F_ALLOW_MULTI the list can have up to BPF_CGROUP_MAX_PROGS 113 - */ 114 - struct list_head progs[MAX_CGROUP_BPF_ATTACH_TYPE]; 115 - u32 flags[MAX_CGROUP_BPF_ATTACH_TYPE]; 116 - 117 - /* list of cgroup shared storages */ 118 - struct list_head storages; 119 - 120 - /* temp storage for effective prog array used by prog_attach/detach */ 121 - struct bpf_prog_array *inactive; 122 - 123 - /* reference counter used to detach bpf programs after cgroup removal */ 124 - struct percpu_ref refcnt; 125 - 126 - /* cgroup_bpf is released using a work queue */ 127 - struct work_struct release_work; 128 128 }; 129 129 130 130 int cgroup_bpf_inherit(struct cgroup *cgrp); ··· 397 451 union bpf_attr __user *uattr); 398 452 #else 399 453 400 - struct cgroup_bpf {}; 401 454 static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; } 402 455 static inline void cgroup_bpf_offline(struct cgroup *cgrp) {} 403 456
+1 -7
include/linux/bpf-netns.h
··· 3 3 #define _BPF_NETNS_H 4 4 5 5 #include <linux/mutex.h> 6 + #include <net/netns/bpf.h> 6 7 #include <uapi/linux/bpf.h> 7 - 8 - enum netns_bpf_attach_type { 9 - NETNS_BPF_INVALID = -1, 10 - NETNS_BPF_FLOW_DISSECTOR = 0, 11 - NETNS_BPF_SK_LOOKUP, 12 - MAX_NETNS_BPF_ATTACH_TYPE 13 - }; 14 8 15 9 static inline enum netns_bpf_attach_type 16 10 to_netns_bpf_attach_type(enum bpf_attach_type attach_type)
+83 -24
include/linux/bpf.h
··· 297 297 298 298 extern const struct bpf_map_ops bpf_map_offload_ops; 299 299 300 + /* bpf_type_flag contains a set of flags that are applicable to the values of 301 + * arg_type, ret_type and reg_type. For example, a pointer value may be null, 302 + * or a memory is read-only. We classify types into two categories: base types 303 + * and extended types. Extended types are base types combined with a type flag. 304 + * 305 + * Currently there are no more than 32 base types in arg_type, ret_type and 306 + * reg_types. 307 + */ 308 + #define BPF_BASE_TYPE_BITS 8 309 + 310 + enum bpf_type_flag { 311 + /* PTR may be NULL. */ 312 + PTR_MAYBE_NULL = BIT(0 + BPF_BASE_TYPE_BITS), 313 + 314 + /* MEM is read-only. When applied on bpf_arg, it indicates the arg is 315 + * compatible with both mutable and immutable memory. 316 + */ 317 + MEM_RDONLY = BIT(1 + BPF_BASE_TYPE_BITS), 318 + 319 + __BPF_TYPE_LAST_FLAG = MEM_RDONLY, 320 + }; 321 + 322 + /* Max number of base types. */ 323 + #define BPF_BASE_TYPE_LIMIT (1UL << BPF_BASE_TYPE_BITS) 324 + 325 + /* Max number of all types. */ 326 + #define BPF_TYPE_LIMIT (__BPF_TYPE_LAST_FLAG | (__BPF_TYPE_LAST_FLAG - 1)) 327 + 300 328 /* function argument constraints */ 301 329 enum bpf_arg_type { 302 330 ARG_DONTCARE = 0, /* unused argument in helper function */ ··· 336 308 ARG_PTR_TO_MAP_KEY, /* pointer to stack used as map key */ 337 309 ARG_PTR_TO_MAP_VALUE, /* pointer to stack used as map value */ 338 310 ARG_PTR_TO_UNINIT_MAP_VALUE, /* pointer to valid memory used to store a map value */ 339 - ARG_PTR_TO_MAP_VALUE_OR_NULL, /* pointer to stack used as map value or NULL */ 340 311 341 312 /* the following constraints used to prototype bpf_memcmp() and other 342 313 * functions that access data on eBPF program stack 343 314 */ 344 315 ARG_PTR_TO_MEM, /* pointer to valid memory (stack, packet, map value) */ 345 - ARG_PTR_TO_MEM_OR_NULL, /* pointer to valid memory or NULL */ 346 316 ARG_PTR_TO_UNINIT_MEM, /* pointer to memory does not need to be initialized, 347 317 * helper function must fill all bytes or clear 348 318 * them in error case. ··· 350 324 ARG_CONST_SIZE_OR_ZERO, /* number of bytes accessed from memory or 0 */ 351 325 352 326 ARG_PTR_TO_CTX, /* pointer to context */ 353 - ARG_PTR_TO_CTX_OR_NULL, /* pointer to context or NULL */ 354 327 ARG_ANYTHING, /* any (initialized) argument is ok */ 355 328 ARG_PTR_TO_SPIN_LOCK, /* pointer to bpf_spin_lock */ 356 329 ARG_PTR_TO_SOCK_COMMON, /* pointer to sock_common */ 357 330 ARG_PTR_TO_INT, /* pointer to int */ 358 331 ARG_PTR_TO_LONG, /* pointer to long */ 359 332 ARG_PTR_TO_SOCKET, /* pointer to bpf_sock (fullsock) */ 360 - ARG_PTR_TO_SOCKET_OR_NULL, /* pointer to bpf_sock (fullsock) or NULL */ 361 333 ARG_PTR_TO_BTF_ID, /* pointer to in-kernel struct */ 362 334 ARG_PTR_TO_ALLOC_MEM, /* pointer to dynamically allocated memory */ 363 - ARG_PTR_TO_ALLOC_MEM_OR_NULL, /* pointer to dynamically allocated memory or NULL */ 364 335 ARG_CONST_ALLOC_SIZE_OR_ZERO, /* number of allocated bytes requested */ 365 336 ARG_PTR_TO_BTF_ID_SOCK_COMMON, /* pointer to in-kernel sock_common or bpf-mirrored bpf_sock */ 366 337 ARG_PTR_TO_PERCPU_BTF_ID, /* pointer to in-kernel percpu type */ 367 338 ARG_PTR_TO_FUNC, /* pointer to a bpf program function */ 368 - ARG_PTR_TO_STACK_OR_NULL, /* pointer to stack or NULL */ 339 + ARG_PTR_TO_STACK, /* pointer to stack */ 369 340 ARG_PTR_TO_CONST_STR, /* pointer to a null terminated read-only string */ 370 341 ARG_PTR_TO_TIMER, /* pointer to bpf_timer */ 371 342 __BPF_ARG_TYPE_MAX, 343 + 344 + /* Extended arg_types. */ 345 + ARG_PTR_TO_MAP_VALUE_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_MAP_VALUE, 346 + ARG_PTR_TO_MEM_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_MEM, 347 + ARG_PTR_TO_CTX_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_CTX, 348 + ARG_PTR_TO_SOCKET_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_SOCKET, 349 + ARG_PTR_TO_ALLOC_MEM_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_ALLOC_MEM, 350 + ARG_PTR_TO_STACK_OR_NULL = PTR_MAYBE_NULL | ARG_PTR_TO_STACK, 351 + 352 + /* This must be the last entry. Its purpose is to ensure the enum is 353 + * wide enough to hold the higher bits reserved for bpf_type_flag. 354 + */ 355 + __BPF_ARG_TYPE_LIMIT = BPF_TYPE_LIMIT, 372 356 }; 357 + static_assert(__BPF_ARG_TYPE_MAX <= BPF_BASE_TYPE_LIMIT); 373 358 374 359 /* type of values returned from helper functions */ 375 360 enum bpf_return_type { 376 361 RET_INTEGER, /* function returns integer */ 377 362 RET_VOID, /* function doesn't return anything */ 378 363 RET_PTR_TO_MAP_VALUE, /* returns a pointer to map elem value */ 379 - RET_PTR_TO_MAP_VALUE_OR_NULL, /* returns a pointer to map elem value or NULL */ 380 - RET_PTR_TO_SOCKET_OR_NULL, /* returns a pointer to a socket or NULL */ 381 - RET_PTR_TO_TCP_SOCK_OR_NULL, /* returns a pointer to a tcp_sock or NULL */ 382 - RET_PTR_TO_SOCK_COMMON_OR_NULL, /* returns a pointer to a sock_common or NULL */ 383 - RET_PTR_TO_ALLOC_MEM_OR_NULL, /* returns a pointer to dynamically allocated memory or NULL */ 384 - RET_PTR_TO_BTF_ID_OR_NULL, /* returns a pointer to a btf_id or NULL */ 385 - RET_PTR_TO_MEM_OR_BTF_ID_OR_NULL, /* returns a pointer to a valid memory or a btf_id or NULL */ 364 + RET_PTR_TO_SOCKET, /* returns a pointer to a socket */ 365 + RET_PTR_TO_TCP_SOCK, /* returns a pointer to a tcp_sock */ 366 + RET_PTR_TO_SOCK_COMMON, /* returns a pointer to a sock_common */ 367 + RET_PTR_TO_ALLOC_MEM, /* returns a pointer to dynamically allocated memory */ 386 368 RET_PTR_TO_MEM_OR_BTF_ID, /* returns a pointer to a valid memory or a btf_id */ 387 369 RET_PTR_TO_BTF_ID, /* returns a pointer to a btf_id */ 370 + __BPF_RET_TYPE_MAX, 371 + 372 + /* Extended ret_types. */ 373 + RET_PTR_TO_MAP_VALUE_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_MAP_VALUE, 374 + RET_PTR_TO_SOCKET_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_SOCKET, 375 + RET_PTR_TO_TCP_SOCK_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_TCP_SOCK, 376 + RET_PTR_TO_SOCK_COMMON_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_SOCK_COMMON, 377 + RET_PTR_TO_ALLOC_MEM_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_ALLOC_MEM, 378 + RET_PTR_TO_BTF_ID_OR_NULL = PTR_MAYBE_NULL | RET_PTR_TO_BTF_ID, 379 + 380 + /* This must be the last entry. Its purpose is to ensure the enum is 381 + * wide enough to hold the higher bits reserved for bpf_type_flag. 382 + */ 383 + __BPF_RET_TYPE_LIMIT = BPF_TYPE_LIMIT, 388 384 }; 385 + static_assert(__BPF_RET_TYPE_MAX <= BPF_BASE_TYPE_LIMIT); 389 386 390 387 /* eBPF function prototype used by verifier to allow BPF_CALLs from eBPF programs 391 388 * to in-kernel helper functions and for adjusting imm32 field in BPF_CALL ··· 470 421 PTR_TO_CTX, /* reg points to bpf_context */ 471 422 CONST_PTR_TO_MAP, /* reg points to struct bpf_map */ 472 423 PTR_TO_MAP_VALUE, /* reg points to map element value */ 473 - PTR_TO_MAP_VALUE_OR_NULL,/* points to map elem value or NULL */ 424 + PTR_TO_MAP_KEY, /* reg points to a map element key */ 474 425 PTR_TO_STACK, /* reg == frame_pointer + offset */ 475 426 PTR_TO_PACKET_META, /* skb->data - meta_len */ 476 427 PTR_TO_PACKET, /* reg points to skb->data */ 477 428 PTR_TO_PACKET_END, /* skb->data + headlen */ 478 429 PTR_TO_FLOW_KEYS, /* reg points to bpf_flow_keys */ 479 430 PTR_TO_SOCKET, /* reg points to struct bpf_sock */ 480 - PTR_TO_SOCKET_OR_NULL, /* reg points to struct bpf_sock or NULL */ 481 431 PTR_TO_SOCK_COMMON, /* reg points to sock_common */ 482 - PTR_TO_SOCK_COMMON_OR_NULL, /* reg points to sock_common or NULL */ 483 432 PTR_TO_TCP_SOCK, /* reg points to struct tcp_sock */ 484 - PTR_TO_TCP_SOCK_OR_NULL, /* reg points to struct tcp_sock or NULL */ 485 433 PTR_TO_TP_BUFFER, /* reg points to a writable raw tp's buffer */ 486 434 PTR_TO_XDP_SOCK, /* reg points to struct xdp_sock */ 487 435 /* PTR_TO_BTF_ID points to a kernel struct that does not need ··· 496 450 * been checked for null. Used primarily to inform the verifier 497 451 * an explicit null check is required for this struct. 498 452 */ 499 - PTR_TO_BTF_ID_OR_NULL, 500 453 PTR_TO_MEM, /* reg points to valid memory region */ 501 - PTR_TO_MEM_OR_NULL, /* reg points to valid memory region or NULL */ 502 - PTR_TO_RDONLY_BUF, /* reg points to a readonly buffer */ 503 - PTR_TO_RDONLY_BUF_OR_NULL, /* reg points to a readonly buffer or NULL */ 504 - PTR_TO_RDWR_BUF, /* reg points to a read/write buffer */ 505 - PTR_TO_RDWR_BUF_OR_NULL, /* reg points to a read/write buffer or NULL */ 454 + PTR_TO_BUF, /* reg points to a read/write buffer */ 506 455 PTR_TO_PERCPU_BTF_ID, /* reg points to a percpu kernel variable */ 507 456 PTR_TO_FUNC, /* reg points to a bpf program function */ 508 - PTR_TO_MAP_KEY, /* reg points to a map element key */ 509 457 __BPF_REG_TYPE_MAX, 458 + 459 + /* Extended reg_types. */ 460 + PTR_TO_MAP_VALUE_OR_NULL = PTR_MAYBE_NULL | PTR_TO_MAP_VALUE, 461 + PTR_TO_SOCKET_OR_NULL = PTR_MAYBE_NULL | PTR_TO_SOCKET, 462 + PTR_TO_SOCK_COMMON_OR_NULL = PTR_MAYBE_NULL | PTR_TO_SOCK_COMMON, 463 + PTR_TO_TCP_SOCK_OR_NULL = PTR_MAYBE_NULL | PTR_TO_TCP_SOCK, 464 + PTR_TO_BTF_ID_OR_NULL = PTR_MAYBE_NULL | PTR_TO_BTF_ID, 465 + 466 + /* This must be the last entry. Its purpose is to ensure the enum is 467 + * wide enough to hold the higher bits reserved for bpf_type_flag. 468 + */ 469 + __BPF_REG_TYPE_LIMIT = BPF_TYPE_LIMIT, 510 470 }; 471 + static_assert(__BPF_REG_TYPE_MAX <= BPF_BASE_TYPE_LIMIT); 511 472 512 473 /* The information passed from prog-specific *_is_valid_access 513 474 * back to the verifier. ··· 830 777 void bpf_ksym_del(struct bpf_ksym *ksym); 831 778 int bpf_jit_charge_modmem(u32 pages); 832 779 void bpf_jit_uncharge_modmem(u32 pages); 780 + bool bpf_prog_has_trampoline(const struct bpf_prog *prog); 833 781 #else 834 782 static inline int bpf_trampoline_link_prog(struct bpf_prog *prog, 835 783 struct bpf_trampoline *tr) ··· 856 802 struct bpf_prog *from, 857 803 struct bpf_prog *to) {} 858 804 static inline bool is_bpf_image_address(unsigned long address) 805 + { 806 + return false; 807 + } 808 + static inline bool bpf_prog_has_trampoline(const struct bpf_prog *prog) 859 809 { 860 810 return false; 861 811 } ··· 2221 2163 extern const struct bpf_func_proto bpf_kallsyms_lookup_name_proto; 2222 2164 extern const struct bpf_func_proto bpf_find_vma_proto; 2223 2165 extern const struct bpf_func_proto bpf_loop_proto; 2166 + extern const struct bpf_func_proto bpf_strncmp_proto; 2224 2167 2225 2168 const struct bpf_func_proto *tracing_prog_func_proto( 2226 2169 enum bpf_func_id func_id, const struct bpf_prog *prog);
+6
include/linux/bpf_local_storage.h
··· 8 8 #define _BPF_LOCAL_STORAGE_H 9 9 10 10 #include <linux/bpf.h> 11 + #include <linux/filter.h> 11 12 #include <linux/rculist.h> 12 13 #include <linux/list.h> 13 14 #include <linux/hash.h> ··· 17 16 18 17 #define BPF_LOCAL_STORAGE_CACHE_SIZE 16 19 18 19 + #define bpf_rcu_lock_held() \ 20 + (rcu_read_lock_held() || rcu_read_lock_trace_held() || \ 21 + rcu_read_lock_bh_held()) 20 22 struct bpf_local_storage_map_bucket { 21 23 struct hlist_head list; 22 24 raw_spinlock_t lock; ··· 164 160 struct bpf_local_storage_data * 165 161 bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap, 166 162 void *value, u64 map_flags); 163 + 164 + void bpf_local_storage_free_rcu(struct rcu_head *rcu); 167 165 168 166 #endif /* _BPF_LOCAL_STORAGE_H */
+27
include/linux/bpf_verifier.h
··· 18 18 * that converting umax_value to int cannot overflow. 19 19 */ 20 20 #define BPF_MAX_VAR_SIZ (1 << 29) 21 + /* size of type_str_buf in bpf_verifier. */ 22 + #define TYPE_STR_BUF_LEN 64 21 23 22 24 /* Liveness marks, used for registers and spilled-regs (in stack slots). 23 25 * Read marks propagate upwards until they find a write mark; they record that ··· 390 388 #define BPF_LOG_LEVEL (BPF_LOG_LEVEL1 | BPF_LOG_LEVEL2) 391 389 #define BPF_LOG_MASK (BPF_LOG_LEVEL | BPF_LOG_STATS) 392 390 #define BPF_LOG_KERNEL (BPF_LOG_MASK + 1) /* kernel internal flag */ 391 + #define BPF_LOG_MIN_ALIGNMENT 8U 392 + #define BPF_LOG_ALIGNMENT 40U 393 393 394 394 static inline bool bpf_verifier_log_needed(const struct bpf_verifier_log *log) 395 395 { ··· 478 474 /* longest register parentage chain walked for liveness marking */ 479 475 u32 longest_mark_read_walk; 480 476 bpfptr_t fd_array; 477 + 478 + /* bit mask to keep track of whether a register has been accessed 479 + * since the last time the function state was printed 480 + */ 481 + u32 scratched_regs; 482 + /* Same as scratched_regs but for stack slots */ 483 + u64 scratched_stack_slots; 484 + u32 prev_log_len, prev_insn_print_len; 485 + /* buffer used in reg_type_str() to generate reg_type string */ 486 + char type_str_buf[TYPE_STR_BUF_LEN]; 481 487 }; 482 488 483 489 __printf(2, 0) void bpf_verifier_vlog(struct bpf_verifier_log *log, ··· 550 536 struct bpf_attach_target_info *tgt_info); 551 537 void bpf_free_kfunc_btf_tab(struct bpf_kfunc_btf_tab *tab); 552 538 539 + #define BPF_BASE_TYPE_MASK GENMASK(BPF_BASE_TYPE_BITS - 1, 0) 540 + 541 + /* extract base type from bpf_{arg, return, reg}_type. */ 542 + static inline u32 base_type(u32 type) 543 + { 544 + return type & BPF_BASE_TYPE_MASK; 545 + } 546 + 547 + /* extract flags from an extended type. See bpf_type_flag in bpf.h. */ 548 + static inline u32 type_flag(u32 type) 549 + { 550 + return type & ~BPF_BASE_TYPE_MASK; 551 + } 553 552 554 553 #endif /* _LINUX_BPF_VERIFIER_H */
+1 -1
include/linux/cgroup-defs.h
··· 19 19 #include <linux/percpu-rwsem.h> 20 20 #include <linux/u64_stats_sync.h> 21 21 #include <linux/workqueue.h> 22 - #include <linux/bpf-cgroup.h> 22 + #include <linux/bpf-cgroup-defs.h> 23 23 #include <linux/psi_types.h> 24 24 25 25 #ifdef CONFIG_CGROUPS
+1
include/linux/dsa/loop.h
··· 2 2 #ifndef DSA_LOOP_H 3 3 #define DSA_LOOP_H 4 4 5 + #include <linux/if_vlan.h> 5 6 #include <linux/types.h> 6 7 #include <linux/ethtool.h> 7 8 #include <net/dsa.h>
+1 -1
include/linux/filter.h
··· 1027 1027 */ 1028 1028 #define xdp_do_flush_map xdp_do_flush 1029 1029 1030 - void bpf_warn_invalid_xdp_action(u32 act); 1030 + void bpf_warn_invalid_xdp_action(struct net_device *dev, struct bpf_prog *prog, u32 act); 1031 1031 1032 1032 #ifdef CONFIG_INET 1033 1033 struct sock *bpf_run_sk_reuseport(struct sock_reuseport *reuse, struct sock *sk,
+1
include/linux/perf_event.h
··· 611 611 #define PERF_ATTACH_SCHED_CB 0x20 612 612 #define PERF_ATTACH_CHILD 0x40 613 613 614 + struct bpf_prog; 614 615 struct perf_cgroup; 615 616 struct perf_buffer; 616 617
+1
include/net/ip6_fib.h
··· 20 20 #include <net/inetpeer.h> 21 21 #include <net/fib_notifier.h> 22 22 #include <linux/indirect_call_wrapper.h> 23 + #include <uapi/linux/bpf.h> 23 24 24 25 #ifdef CONFIG_IPV6_MULTIPLE_TABLES 25 26 #define FIB6_TABLE_HASHSZ 256
+2
include/net/ipv6.h
··· 21 21 #include <net/snmp.h> 22 22 #include <net/netns/hash.h> 23 23 24 + struct ip_tunnel_info; 25 + 24 26 #define SIN6_LEN_RFC2133 24 25 27 26 28 #define IPV6_MAXPLEN 65535
+8 -1
include/net/netns/bpf.h
··· 6 6 #ifndef __NETNS_BPF_H__ 7 7 #define __NETNS_BPF_H__ 8 8 9 - #include <linux/bpf-netns.h> 9 + #include <linux/list.h> 10 10 11 11 struct bpf_prog; 12 12 struct bpf_prog_array; 13 + 14 + enum netns_bpf_attach_type { 15 + NETNS_BPF_INVALID = -1, 16 + NETNS_BPF_FLOW_DISSECTOR = 0, 17 + NETNS_BPF_SK_LOOKUP, 18 + MAX_NETNS_BPF_ATTACH_TYPE 19 + }; 13 20 14 21 struct netns_bpf { 15 22 /* Array of programs to run compiled from progs or links */
+1
include/net/route.h
··· 43 43 #define RT_CONN_FLAGS(sk) (RT_TOS(inet_sk(sk)->tos) | sock_flag(sk, SOCK_LOCALROUTE)) 44 44 #define RT_CONN_FLAGS_TOS(sk,tos) (RT_TOS(tos) | sock_flag(sk, SOCK_LOCALROUTE)) 45 45 46 + struct ip_tunnel_info; 46 47 struct fib_nh; 47 48 struct fib_info; 48 49 struct uncached_list;
+1 -1
include/net/sock.h
··· 56 56 #include <linux/wait.h> 57 57 #include <linux/cgroup-defs.h> 58 58 #include <linux/rbtree.h> 59 - #include <linux/filter.h> 60 59 #include <linux/rculist_nulls.h> 61 60 #include <linux/poll.h> 62 61 #include <linux/sockptr.h> ··· 248 249 }; 249 250 250 251 struct bpf_local_storage; 252 + struct sk_filter; 251 253 252 254 /** 253 255 * struct sock - network layer representation of sockets
-1
include/net/xdp_priv.h
··· 10 10 union { 11 11 void *allocator; 12 12 struct page_pool *page_pool; 13 - struct zero_copy_allocator *zc_alloc; 14 13 }; 15 14 struct rhash_head node; 16 15 struct rcu_head rcu;
+1
include/net/xdp_sock.h
··· 6 6 #ifndef _LINUX_XDP_SOCK_H 7 7 #define _LINUX_XDP_SOCK_H 8 8 9 + #include <linux/bpf.h> 9 10 #include <linux/workqueue.h> 10 11 #include <linux/if_xdp.h> 11 12 #include <linux/mutex.h>
+39
include/uapi/linux/bpf.h
··· 4983 4983 * Return 4984 4984 * The number of loops performed, **-EINVAL** for invalid **flags**, 4985 4985 * **-E2BIG** if **nr_loops** exceeds the maximum number of loops. 4986 + * 4987 + * long bpf_strncmp(const char *s1, u32 s1_sz, const char *s2) 4988 + * Description 4989 + * Do strncmp() between **s1** and **s2**. **s1** doesn't need 4990 + * to be null-terminated and **s1_sz** is the maximum storage 4991 + * size of **s1**. **s2** must be a read-only string. 4992 + * Return 4993 + * An integer less than, equal to, or greater than zero 4994 + * if the first **s1_sz** bytes of **s1** is found to be 4995 + * less than, to match, or be greater than **s2**. 4996 + * 4997 + * long bpf_get_func_arg(void *ctx, u32 n, u64 *value) 4998 + * Description 4999 + * Get **n**-th argument (zero based) of the traced function (for tracing programs) 5000 + * returned in **value**. 5001 + * 5002 + * Return 5003 + * 0 on success. 5004 + * **-EINVAL** if n >= arguments count of traced function. 5005 + * 5006 + * long bpf_get_func_ret(void *ctx, u64 *value) 5007 + * Description 5008 + * Get return value of the traced function (for tracing programs) 5009 + * in **value**. 5010 + * 5011 + * Return 5012 + * 0 on success. 5013 + * **-EOPNOTSUPP** for tracing programs other than BPF_TRACE_FEXIT or BPF_MODIFY_RETURN. 5014 + * 5015 + * long bpf_get_func_arg_cnt(void *ctx) 5016 + * Description 5017 + * Get number of arguments of the traced function (for tracing programs). 5018 + * 5019 + * Return 5020 + * The number of arguments of the traced function. 4986 5021 */ 4987 5022 #define __BPF_FUNC_MAPPER(FN) \ 4988 5023 FN(unspec), \ ··· 5202 5167 FN(kallsyms_lookup_name), \ 5203 5168 FN(find_vma), \ 5204 5169 FN(loop), \ 5170 + FN(strncmp), \ 5171 + FN(get_func_arg), \ 5172 + FN(get_func_ret), \ 5173 + FN(get_func_arg_cnt), \ 5205 5174 /* */ 5206 5175 5207 5176 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
+6
kernel/bpf/bloom_filter.c
··· 82 82 return -EOPNOTSUPP; 83 83 } 84 84 85 + static int bloom_map_get_next_key(struct bpf_map *map, void *key, void *next_key) 86 + { 87 + return -EOPNOTSUPP; 88 + } 89 + 85 90 static struct bpf_map *bloom_map_alloc(union bpf_attr *attr) 86 91 { 87 92 u32 bitset_bytes, bitset_mask, nr_hash_funcs, nr_bits; ··· 197 192 .map_meta_equal = bpf_map_meta_equal, 198 193 .map_alloc = bloom_map_alloc, 199 194 .map_free = bloom_map_free, 195 + .map_get_next_key = bloom_map_get_next_key, 200 196 .map_push_elem = bloom_map_push_elem, 201 197 .map_peek_elem = bloom_map_peek_elem, 202 198 .map_pop_elem = bloom_map_pop_elem,
+5 -1
kernel/bpf/bpf_inode_storage.c
··· 17 17 #include <linux/bpf_lsm.h> 18 18 #include <linux/btf_ids.h> 19 19 #include <linux/fdtable.h> 20 + #include <linux/rcupdate_trace.h> 20 21 21 22 DEFINE_BPF_STORAGE_CACHE(inode_cache); 22 23 ··· 45 44 if (!bsb) 46 45 return NULL; 47 46 48 - inode_storage = rcu_dereference(bsb->storage); 47 + inode_storage = 48 + rcu_dereference_check(bsb->storage, bpf_rcu_lock_held()); 49 49 if (!inode_storage) 50 50 return NULL; 51 51 ··· 174 172 { 175 173 struct bpf_local_storage_data *sdata; 176 174 175 + WARN_ON_ONCE(!bpf_rcu_lock_held()); 177 176 if (flags & ~(BPF_LOCAL_STORAGE_GET_F_CREATE)) 178 177 return (unsigned long)NULL; 179 178 ··· 207 204 BPF_CALL_2(bpf_inode_storage_delete, 208 205 struct bpf_map *, map, struct inode *, inode) 209 206 { 207 + WARN_ON_ONCE(!bpf_rcu_lock_held()); 210 208 if (!inode) 211 209 return -EINVAL; 212 210
+37 -13
kernel/bpf/bpf_local_storage.c
··· 11 11 #include <net/sock.h> 12 12 #include <uapi/linux/sock_diag.h> 13 13 #include <uapi/linux/btf.h> 14 + #include <linux/rcupdate.h> 15 + #include <linux/rcupdate_trace.h> 16 + #include <linux/rcupdate_wait.h> 14 17 15 18 #define BPF_LOCAL_STORAGE_CREATE_FLAG_MASK (BPF_F_NO_PREALLOC | BPF_F_CLONE) 16 19 ··· 84 81 return NULL; 85 82 } 86 83 84 + void bpf_local_storage_free_rcu(struct rcu_head *rcu) 85 + { 86 + struct bpf_local_storage *local_storage; 87 + 88 + local_storage = container_of(rcu, struct bpf_local_storage, rcu); 89 + kfree_rcu(local_storage, rcu); 90 + } 91 + 92 + static void bpf_selem_free_rcu(struct rcu_head *rcu) 93 + { 94 + struct bpf_local_storage_elem *selem; 95 + 96 + selem = container_of(rcu, struct bpf_local_storage_elem, rcu); 97 + kfree_rcu(selem, rcu); 98 + } 99 + 87 100 /* local_storage->lock must be held and selem->local_storage == local_storage. 88 101 * The caller must ensure selem->smap is still valid to be 89 102 * dereferenced for its smap->elem_size and smap->cache_idx. ··· 112 93 bool free_local_storage; 113 94 void *owner; 114 95 115 - smap = rcu_dereference(SDATA(selem)->smap); 96 + smap = rcu_dereference_check(SDATA(selem)->smap, bpf_rcu_lock_held()); 116 97 owner = local_storage->owner; 117 98 118 99 /* All uncharging on the owner must be done first. ··· 137 118 * 138 119 * Although the unlock will be done under 139 120 * rcu_read_lock(), it is more intutivie to 140 - * read if kfree_rcu(local_storage, rcu) is done 121 + * read if the freeing of the storage is done 141 122 * after the raw_spin_unlock_bh(&local_storage->lock). 142 123 * 143 124 * Hence, a "bool free_local_storage" is returned 144 - * to the caller which then calls the kfree_rcu() 145 - * after unlock. 125 + * to the caller which then calls then frees the storage after 126 + * all the RCU grace periods have expired. 146 127 */ 147 128 } 148 129 hlist_del_init_rcu(&selem->snode); ··· 150 131 SDATA(selem)) 151 132 RCU_INIT_POINTER(local_storage->cache[smap->cache_idx], NULL); 152 133 153 - kfree_rcu(selem, rcu); 154 - 134 + call_rcu_tasks_trace(&selem->rcu, bpf_selem_free_rcu); 155 135 return free_local_storage; 156 136 } 157 137 ··· 164 146 /* selem has already been unlinked from sk */ 165 147 return; 166 148 167 - local_storage = rcu_dereference(selem->local_storage); 149 + local_storage = rcu_dereference_check(selem->local_storage, 150 + bpf_rcu_lock_held()); 168 151 raw_spin_lock_irqsave(&local_storage->lock, flags); 169 152 if (likely(selem_linked_to_storage(selem))) 170 153 free_local_storage = bpf_selem_unlink_storage_nolock( ··· 173 154 raw_spin_unlock_irqrestore(&local_storage->lock, flags); 174 155 175 156 if (free_local_storage) 176 - kfree_rcu(local_storage, rcu); 157 + call_rcu_tasks_trace(&local_storage->rcu, 158 + bpf_local_storage_free_rcu); 177 159 } 178 160 179 161 void bpf_selem_link_storage_nolock(struct bpf_local_storage *local_storage, ··· 194 174 /* selem has already be unlinked from smap */ 195 175 return; 196 176 197 - smap = rcu_dereference(SDATA(selem)->smap); 177 + smap = rcu_dereference_check(SDATA(selem)->smap, bpf_rcu_lock_held()); 198 178 b = select_bucket(smap, selem); 199 179 raw_spin_lock_irqsave(&b->lock, flags); 200 180 if (likely(selem_linked_to_map(selem))) ··· 233 213 struct bpf_local_storage_elem *selem; 234 214 235 215 /* Fast path (cache hit) */ 236 - sdata = rcu_dereference(local_storage->cache[smap->cache_idx]); 216 + sdata = rcu_dereference_check(local_storage->cache[smap->cache_idx], 217 + bpf_rcu_lock_held()); 237 218 if (sdata && rcu_access_pointer(sdata->smap) == smap) 238 219 return sdata; 239 220 240 221 /* Slow path (cache miss) */ 241 - hlist_for_each_entry_rcu(selem, &local_storage->list, snode) 222 + hlist_for_each_entry_rcu(selem, &local_storage->list, snode, 223 + rcu_read_lock_trace_held()) 242 224 if (rcu_access_pointer(SDATA(selem)->smap) == smap) 243 225 break; 244 226 ··· 328 306 * bucket->list, first_selem can be freed immediately 329 307 * (instead of kfree_rcu) because 330 308 * bpf_local_storage_map_free() does a 331 - * synchronize_rcu() before walking the bucket->list. 309 + * synchronize_rcu_mult (waiting for both sleepable and 310 + * normal programs) before walking the bucket->list. 332 311 * Hence, no one is accessing selem from the 333 312 * bucket->list under rcu_read_lock(). 334 313 */ ··· 365 342 !map_value_has_spin_lock(&smap->map))) 366 343 return ERR_PTR(-EINVAL); 367 344 368 - local_storage = rcu_dereference(*owner_storage(smap, owner)); 345 + local_storage = rcu_dereference_check(*owner_storage(smap, owner), 346 + bpf_rcu_lock_held()); 369 347 if (!local_storage || hlist_empty(&local_storage->list)) { 370 348 /* Very first elem for the owner */ 371 349 err = check_flags(NULL, map_flags);
+5 -1
kernel/bpf/bpf_task_storage.c
··· 17 17 #include <uapi/linux/btf.h> 18 18 #include <linux/btf_ids.h> 19 19 #include <linux/fdtable.h> 20 + #include <linux/rcupdate_trace.h> 20 21 21 22 DEFINE_BPF_STORAGE_CACHE(task_cache); 22 23 ··· 60 59 struct bpf_local_storage *task_storage; 61 60 struct bpf_local_storage_map *smap; 62 61 63 - task_storage = rcu_dereference(task->bpf_storage); 62 + task_storage = 63 + rcu_dereference_check(task->bpf_storage, bpf_rcu_lock_held()); 64 64 if (!task_storage) 65 65 return NULL; 66 66 ··· 231 229 { 232 230 struct bpf_local_storage_data *sdata; 233 231 232 + WARN_ON_ONCE(!bpf_rcu_lock_held()); 234 233 if (flags & ~(BPF_LOCAL_STORAGE_GET_F_CREATE)) 235 234 return (unsigned long)NULL; 236 235 ··· 263 260 { 264 261 int ret; 265 262 263 + WARN_ON_ONCE(!bpf_rcu_lock_held()); 266 264 if (!task) 267 265 return -EINVAL; 268 266
+88 -36
kernel/bpf/btf.c
··· 4826 4826 return prog->aux->attach_btf; 4827 4827 } 4828 4828 4829 - static bool is_string_ptr(struct btf *btf, const struct btf_type *t) 4829 + static bool is_int_ptr(struct btf *btf, const struct btf_type *t) 4830 4830 { 4831 4831 /* t comes in already as a pointer */ 4832 4832 t = btf_type_by_id(btf, t->type); ··· 4835 4835 if (BTF_INFO_KIND(t->info) == BTF_KIND_CONST) 4836 4836 t = btf_type_by_id(btf, t->type); 4837 4837 4838 - /* char, signed char, unsigned char */ 4839 - return btf_type_is_int(t) && t->size == 1; 4838 + return btf_type_is_int(t); 4840 4839 } 4841 4840 4842 4841 bool btf_ctx_access(int off, int size, enum bpf_access_type type, ··· 4940 4941 /* check for PTR_TO_RDONLY_BUF_OR_NULL or PTR_TO_RDWR_BUF_OR_NULL */ 4941 4942 for (i = 0; i < prog->aux->ctx_arg_info_size; i++) { 4942 4943 const struct bpf_ctx_arg_aux *ctx_arg_info = &prog->aux->ctx_arg_info[i]; 4944 + u32 type, flag; 4943 4945 4944 - if (ctx_arg_info->offset == off && 4945 - (ctx_arg_info->reg_type == PTR_TO_RDONLY_BUF_OR_NULL || 4946 - ctx_arg_info->reg_type == PTR_TO_RDWR_BUF_OR_NULL)) { 4946 + type = base_type(ctx_arg_info->reg_type); 4947 + flag = type_flag(ctx_arg_info->reg_type); 4948 + if (ctx_arg_info->offset == off && type == PTR_TO_BUF && 4949 + (flag & PTR_MAYBE_NULL)) { 4947 4950 info->reg_type = ctx_arg_info->reg_type; 4948 4951 return true; 4949 4952 } ··· 4958 4957 */ 4959 4958 return true; 4960 4959 4961 - if (is_string_ptr(btf, t)) 4960 + if (is_int_ptr(btf, t)) 4962 4961 return true; 4963 4962 4964 4963 /* this is a pointer to another type */ ··· 5576 5575 #endif 5577 5576 }; 5578 5577 5578 + /* Returns true if struct is composed of scalars, 4 levels of nesting allowed */ 5579 + static bool __btf_type_is_scalar_struct(struct bpf_verifier_log *log, 5580 + const struct btf *btf, 5581 + const struct btf_type *t, int rec) 5582 + { 5583 + const struct btf_type *member_type; 5584 + const struct btf_member *member; 5585 + u32 i; 5586 + 5587 + if (!btf_type_is_struct(t)) 5588 + return false; 5589 + 5590 + for_each_member(i, t, member) { 5591 + const struct btf_array *array; 5592 + 5593 + member_type = btf_type_skip_modifiers(btf, member->type, NULL); 5594 + if (btf_type_is_struct(member_type)) { 5595 + if (rec >= 3) { 5596 + bpf_log(log, "max struct nesting depth exceeded\n"); 5597 + return false; 5598 + } 5599 + if (!__btf_type_is_scalar_struct(log, btf, member_type, rec + 1)) 5600 + return false; 5601 + continue; 5602 + } 5603 + if (btf_type_is_array(member_type)) { 5604 + array = btf_type_array(member_type); 5605 + if (!array->nelems) 5606 + return false; 5607 + member_type = btf_type_skip_modifiers(btf, array->type, NULL); 5608 + if (!btf_type_is_scalar(member_type)) 5609 + return false; 5610 + continue; 5611 + } 5612 + if (!btf_type_is_scalar(member_type)) 5613 + return false; 5614 + } 5615 + return true; 5616 + } 5617 + 5579 5618 static int btf_check_func_arg_match(struct bpf_verifier_env *env, 5580 5619 const struct btf *btf, u32 func_id, 5581 5620 struct bpf_reg_state *regs, 5582 5621 bool ptr_to_mem_ok) 5583 5622 { 5584 5623 struct bpf_verifier_log *log = &env->log; 5624 + bool is_kfunc = btf_is_kernel(btf); 5585 5625 const char *func_name, *ref_tname; 5586 5626 const struct btf_type *t, *ref_t; 5587 5627 const struct btf_param *args; ··· 5675 5633 5676 5634 ref_t = btf_type_skip_modifiers(btf, t->type, &ref_id); 5677 5635 ref_tname = btf_name_by_offset(btf, ref_t->name_off); 5678 - if (btf_is_kernel(btf)) { 5636 + if (btf_get_prog_ctx_type(log, btf, t, 5637 + env->prog->type, i)) { 5638 + /* If function expects ctx type in BTF check that caller 5639 + * is passing PTR_TO_CTX. 5640 + */ 5641 + if (reg->type != PTR_TO_CTX) { 5642 + bpf_log(log, 5643 + "arg#%d expected pointer to ctx, but got %s\n", 5644 + i, btf_type_str(t)); 5645 + return -EINVAL; 5646 + } 5647 + if (check_ctx_reg(env, reg, regno)) 5648 + return -EINVAL; 5649 + } else if (is_kfunc && (reg->type == PTR_TO_BTF_ID || reg2btf_ids[reg->type])) { 5679 5650 const struct btf_type *reg_ref_t; 5680 5651 const struct btf *reg_btf; 5681 5652 const char *reg_ref_tname; ··· 5704 5649 if (reg->type == PTR_TO_BTF_ID) { 5705 5650 reg_btf = reg->btf; 5706 5651 reg_ref_id = reg->btf_id; 5707 - } else if (reg2btf_ids[reg->type]) { 5652 + } else { 5708 5653 reg_btf = btf_vmlinux; 5709 5654 reg_ref_id = *reg2btf_ids[reg->type]; 5710 - } else { 5711 - bpf_log(log, "kernel function %s args#%d expected pointer to %s %s but R%d is not a pointer to btf_id\n", 5712 - func_name, i, 5713 - btf_type_str(ref_t), ref_tname, regno); 5714 - return -EINVAL; 5715 5655 } 5716 5656 5717 5657 reg_ref_t = btf_type_skip_modifiers(reg_btf, reg_ref_id, ··· 5722 5672 reg_ref_tname); 5723 5673 return -EINVAL; 5724 5674 } 5725 - } else if (btf_get_prog_ctx_type(log, btf, t, 5726 - env->prog->type, i)) { 5727 - /* If function expects ctx type in BTF check that caller 5728 - * is passing PTR_TO_CTX. 5729 - */ 5730 - if (reg->type != PTR_TO_CTX) { 5731 - bpf_log(log, 5732 - "arg#%d expected pointer to ctx, but got %s\n", 5733 - i, btf_type_str(t)); 5734 - return -EINVAL; 5735 - } 5736 - if (check_ctx_reg(env, reg, regno)) 5737 - return -EINVAL; 5738 5675 } else if (ptr_to_mem_ok) { 5739 5676 const struct btf_type *resolve_ret; 5740 5677 u32 type_size; 5678 + 5679 + if (is_kfunc) { 5680 + /* Permit pointer to mem, but only when argument 5681 + * type is pointer to scalar, or struct composed 5682 + * (recursively) of scalars. 5683 + */ 5684 + if (!btf_type_is_scalar(ref_t) && 5685 + !__btf_type_is_scalar_struct(log, btf, ref_t, 0)) { 5686 + bpf_log(log, 5687 + "arg#%d pointer type %s %s must point to scalar or struct with scalar\n", 5688 + i, btf_type_str(ref_t), ref_tname); 5689 + return -EINVAL; 5690 + } 5691 + } 5741 5692 5742 5693 resolve_ret = btf_resolve_size(btf, ref_t, &type_size); 5743 5694 if (IS_ERR(resolve_ret)) { ··· 5752 5701 if (check_mem_reg(env, reg, regno, type_size)) 5753 5702 return -EINVAL; 5754 5703 } else { 5704 + bpf_log(log, "reg type unsupported for arg#%d %sfunction %s#%d\n", i, 5705 + is_kfunc ? "kernel " : "", func_name, func_id); 5755 5706 return -EINVAL; 5756 5707 } 5757 5708 } ··· 5803 5750 const struct btf *btf, u32 func_id, 5804 5751 struct bpf_reg_state *regs) 5805 5752 { 5806 - return btf_check_func_arg_match(env, btf, func_id, regs, false); 5753 + return btf_check_func_arg_match(env, btf, func_id, regs, true); 5807 5754 } 5808 5755 5809 5756 /* Convert BTF of a function into bpf_reg_state if possible ··· 5911 5858 return -EINVAL; 5912 5859 } 5913 5860 5914 - reg->type = PTR_TO_MEM_OR_NULL; 5861 + reg->type = PTR_TO_MEM | PTR_MAYBE_NULL; 5915 5862 reg->id = ++env->id_gen; 5916 5863 5917 5864 continue; ··· 6405 6352 .func = bpf_btf_find_by_name_kind, 6406 6353 .gpl_only = false, 6407 6354 .ret_type = RET_INTEGER, 6408 - .arg1_type = ARG_PTR_TO_MEM, 6355 + .arg1_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6409 6356 .arg2_type = ARG_CONST_SIZE, 6410 6357 .arg3_type = ARG_ANYTHING, 6411 6358 .arg4_type = ARG_ANYTHING, ··· 6587 6534 bpf_free_cands_from_cache(*cc); 6588 6535 *cc = NULL; 6589 6536 } 6590 - new_cands = kmalloc(sizeof_cands(cands->cnt), GFP_KERNEL); 6537 + new_cands = kmemdup(cands, sizeof_cands(cands->cnt), GFP_KERNEL); 6591 6538 if (!new_cands) { 6592 6539 bpf_free_cands(cands); 6593 6540 return ERR_PTR(-ENOMEM); 6594 6541 } 6595 - memcpy(new_cands, cands, sizeof_cands(cands->cnt)); 6596 6542 /* strdup the name, since it will stay in cache. 6597 6543 * the cands->name points to strings in prog's BTF and the prog can be unloaded. 6598 6544 */ ··· 6709 6657 6710 6658 main_btf = bpf_get_btf_vmlinux(); 6711 6659 if (IS_ERR(main_btf)) 6712 - return (void *)main_btf; 6660 + return ERR_CAST(main_btf); 6713 6661 6714 6662 local_type = btf_type_by_id(local_btf, local_type_id); 6715 6663 if (!local_type) ··· 6736 6684 /* Attempt to find target candidates in vmlinux BTF first */ 6737 6685 cands = bpf_core_add_cands(cands, main_btf, 1); 6738 6686 if (IS_ERR(cands)) 6739 - return cands; 6687 + return ERR_CAST(cands); 6740 6688 6741 6689 /* cands is a pointer to kmalloced memory here if cands->cnt > 0 */ 6742 6690 6743 6691 /* populate cache even when cands->cnt == 0 */ 6744 6692 cc = populate_cand_cache(cands, vmlinux_cand_cache, VMLINUX_CAND_CACHE_SIZE); 6745 6693 if (IS_ERR(cc)) 6746 - return cc; 6694 + return ERR_CAST(cc); 6747 6695 6748 6696 /* if vmlinux BTF has any candidate, don't go for module BTFs */ 6749 6697 if (cc->cnt) ··· 6769 6717 cands = bpf_core_add_cands(cands, mod_btf, btf_nr_types(main_btf)); 6770 6718 if (IS_ERR(cands)) { 6771 6719 btf_put(mod_btf); 6772 - return cands; 6720 + return ERR_CAST(cands); 6773 6721 } 6774 6722 spin_lock_bh(&btf_idr_lock); 6775 6723 btf_put(mod_btf);
+1 -1
kernel/bpf/cgroup.c
··· 1789 1789 .gpl_only = false, 1790 1790 .ret_type = RET_INTEGER, 1791 1791 .arg1_type = ARG_PTR_TO_CTX, 1792 - .arg2_type = ARG_PTR_TO_MEM, 1792 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 1793 1793 .arg3_type = ARG_CONST_SIZE, 1794 1794 }; 1795 1795
+2 -2
kernel/bpf/cpumap.c
··· 195 195 } 196 196 return; 197 197 default: 198 - bpf_warn_invalid_xdp_action(act); 198 + bpf_warn_invalid_xdp_action(NULL, rcpu->prog, act); 199 199 fallthrough; 200 200 case XDP_ABORTED: 201 201 trace_xdp_exception(skb->dev, rcpu->prog, act); ··· 254 254 } 255 255 break; 256 256 default: 257 - bpf_warn_invalid_xdp_action(act); 257 + bpf_warn_invalid_xdp_action(NULL, rcpu->prog, act); 258 258 fallthrough; 259 259 case XDP_DROP: 260 260 xdp_return_frame(xdpf);
+2 -2
kernel/bpf/devmap.c
··· 348 348 frames[nframes++] = xdpf; 349 349 break; 350 350 default: 351 - bpf_warn_invalid_xdp_action(act); 351 + bpf_warn_invalid_xdp_action(NULL, xdp_prog, act); 352 352 fallthrough; 353 353 case XDP_ABORTED: 354 354 trace_xdp_exception(dev, xdp_prog, act); ··· 507 507 __skb_push(skb, skb->mac_len); 508 508 break; 509 509 default: 510 - bpf_warn_invalid_xdp_action(act); 510 + bpf_warn_invalid_xdp_action(NULL, dst->xdp_prog, act); 511 511 fallthrough; 512 512 case XDP_ABORTED: 513 513 trace_xdp_exception(dst->dev, dst->xdp_prog, act);
+23 -6
kernel/bpf/helpers.c
··· 2 2 /* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com 3 3 */ 4 4 #include <linux/bpf.h> 5 + #include <linux/bpf-cgroup.h> 5 6 #include <linux/rcupdate.h> 6 7 #include <linux/random.h> 7 8 #include <linux/smp.h> ··· 531 530 .func = bpf_strtol, 532 531 .gpl_only = false, 533 532 .ret_type = RET_INTEGER, 534 - .arg1_type = ARG_PTR_TO_MEM, 533 + .arg1_type = ARG_PTR_TO_MEM | MEM_RDONLY, 535 534 .arg2_type = ARG_CONST_SIZE, 536 535 .arg3_type = ARG_ANYTHING, 537 536 .arg4_type = ARG_PTR_TO_LONG, ··· 559 558 .func = bpf_strtoul, 560 559 .gpl_only = false, 561 560 .ret_type = RET_INTEGER, 562 - .arg1_type = ARG_PTR_TO_MEM, 561 + .arg1_type = ARG_PTR_TO_MEM | MEM_RDONLY, 563 562 .arg2_type = ARG_CONST_SIZE, 564 563 .arg3_type = ARG_ANYTHING, 565 564 .arg4_type = ARG_PTR_TO_LONG, 566 565 }; 567 566 #endif 567 + 568 + BPF_CALL_3(bpf_strncmp, const char *, s1, u32, s1_sz, const char *, s2) 569 + { 570 + return strncmp(s1, s2, s1_sz); 571 + } 572 + 573 + const struct bpf_func_proto bpf_strncmp_proto = { 574 + .func = bpf_strncmp, 575 + .gpl_only = false, 576 + .ret_type = RET_INTEGER, 577 + .arg1_type = ARG_PTR_TO_MEM, 578 + .arg2_type = ARG_CONST_SIZE, 579 + .arg3_type = ARG_PTR_TO_CONST_STR, 580 + }; 568 581 569 582 BPF_CALL_4(bpf_get_ns_current_pid_tgid, u64, dev, u64, ino, 570 583 struct bpf_pidns_info *, nsdata, u32, size) ··· 645 630 .arg1_type = ARG_PTR_TO_CTX, 646 631 .arg2_type = ARG_CONST_MAP_PTR, 647 632 .arg3_type = ARG_ANYTHING, 648 - .arg4_type = ARG_PTR_TO_MEM, 633 + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 649 634 .arg5_type = ARG_CONST_SIZE_OR_ZERO, 650 635 }; 651 636 ··· 682 667 const struct bpf_func_proto bpf_per_cpu_ptr_proto = { 683 668 .func = bpf_per_cpu_ptr, 684 669 .gpl_only = false, 685 - .ret_type = RET_PTR_TO_MEM_OR_BTF_ID_OR_NULL, 670 + .ret_type = RET_PTR_TO_MEM_OR_BTF_ID | PTR_MAYBE_NULL | MEM_RDONLY, 686 671 .arg1_type = ARG_PTR_TO_PERCPU_BTF_ID, 687 672 .arg2_type = ARG_ANYTHING, 688 673 }; ··· 695 680 const struct bpf_func_proto bpf_this_cpu_ptr_proto = { 696 681 .func = bpf_this_cpu_ptr, 697 682 .gpl_only = false, 698 - .ret_type = RET_PTR_TO_MEM_OR_BTF_ID, 683 + .ret_type = RET_PTR_TO_MEM_OR_BTF_ID | MEM_RDONLY, 699 684 .arg1_type = ARG_PTR_TO_PERCPU_BTF_ID, 700 685 }; 701 686 ··· 1026 1011 .arg1_type = ARG_PTR_TO_MEM_OR_NULL, 1027 1012 .arg2_type = ARG_CONST_SIZE_OR_ZERO, 1028 1013 .arg3_type = ARG_PTR_TO_CONST_STR, 1029 - .arg4_type = ARG_PTR_TO_MEM_OR_NULL, 1014 + .arg4_type = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY, 1030 1015 .arg5_type = ARG_CONST_SIZE_OR_ZERO, 1031 1016 }; 1032 1017 ··· 1393 1378 return &bpf_for_each_map_elem_proto; 1394 1379 case BPF_FUNC_loop: 1395 1380 return &bpf_loop_proto; 1381 + case BPF_FUNC_strncmp: 1382 + return &bpf_strncmp_proto; 1396 1383 default: 1397 1384 break; 1398 1385 }
+1 -2
kernel/bpf/local_storage.c
··· 163 163 return 0; 164 164 } 165 165 166 - new = bpf_map_kmalloc_node(map, sizeof(struct bpf_storage_buffer) + 167 - map->value_size, 166 + new = bpf_map_kmalloc_node(map, struct_size(new, data, map->value_size), 168 167 __GFP_ZERO | GFP_ATOMIC | __GFP_NOWARN, 169 168 map->numa_node); 170 169 if (!new)
+1 -1
kernel/bpf/lpm_trie.c
··· 412 412 rcu_assign_pointer(im_node->child[1], node); 413 413 } 414 414 415 - /* Finally, assign the intermediate node to the determined spot */ 415 + /* Finally, assign the intermediate node to the determined slot */ 416 416 rcu_assign_pointer(*slot, im_node); 417 417 418 418 out:
+2 -2
kernel/bpf/map_iter.c
··· 174 174 .ctx_arg_info_size = 2, 175 175 .ctx_arg_info = { 176 176 { offsetof(struct bpf_iter__bpf_map_elem, key), 177 - PTR_TO_RDONLY_BUF_OR_NULL }, 177 + PTR_TO_BUF | PTR_MAYBE_NULL | MEM_RDONLY }, 178 178 { offsetof(struct bpf_iter__bpf_map_elem, value), 179 - PTR_TO_RDWR_BUF_OR_NULL }, 179 + PTR_TO_BUF | PTR_MAYBE_NULL }, 180 180 }, 181 181 }; 182 182
+1
kernel/bpf/net_namespace.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 3 3 #include <linux/bpf.h> 4 + #include <linux/bpf-netns.h> 4 5 #include <linux/filter.h> 5 6 #include <net/net_namespace.h> 6 7
+1 -5
kernel/bpf/reuseport_array.c
··· 152 152 { 153 153 int numa_node = bpf_map_attr_numa_node(attr); 154 154 struct reuseport_array *array; 155 - u64 array_size; 156 155 157 156 if (!bpf_capable()) 158 157 return ERR_PTR(-EPERM); 159 158 160 - array_size = sizeof(*array); 161 - array_size += (u64)attr->max_entries * sizeof(struct sock *); 162 - 163 159 /* allocate all map elements and zero-initialize them */ 164 - array = bpf_map_area_alloc(array_size, numa_node); 160 + array = bpf_map_area_alloc(struct_size(array, ptrs, attr->max_entries), numa_node); 165 161 if (!array) 166 162 return ERR_PTR(-ENOMEM); 167 163
+1 -1
kernel/bpf/ringbuf.c
··· 444 444 .func = bpf_ringbuf_output, 445 445 .ret_type = RET_INTEGER, 446 446 .arg1_type = ARG_CONST_MAP_PTR, 447 - .arg2_type = ARG_PTR_TO_MEM, 447 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 448 448 .arg3_type = ARG_CONST_SIZE_OR_ZERO, 449 449 .arg4_type = ARG_ANYTHING, 450 450 };
+2 -1
kernel/bpf/syscall.c
··· 2 2 /* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com 3 3 */ 4 4 #include <linux/bpf.h> 5 + #include <linux/bpf-cgroup.h> 5 6 #include <linux/bpf_trace.h> 6 7 #include <linux/bpf_lirc.h> 7 8 #include <linux/bpf_verifier.h> ··· 4773 4772 .gpl_only = false, 4774 4773 .ret_type = RET_INTEGER, 4775 4774 .arg1_type = ARG_ANYTHING, 4776 - .arg2_type = ARG_PTR_TO_MEM, 4775 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 4777 4776 .arg3_type = ARG_CONST_SIZE, 4778 4777 }; 4779 4778
+8
kernel/bpf/trampoline.c
··· 27 27 /* serializes access to trampoline_table */ 28 28 static DEFINE_MUTEX(trampoline_mutex); 29 29 30 + bool bpf_prog_has_trampoline(const struct bpf_prog *prog) 31 + { 32 + enum bpf_attach_type eatype = prog->expected_attach_type; 33 + 34 + return eatype == BPF_TRACE_FENTRY || eatype == BPF_TRACE_FEXIT || 35 + eatype == BPF_MODIFY_RETURN; 36 + } 37 + 30 38 void *bpf_jit_alloc_exec_page(void) 31 39 { 32 40 void *image;
+415 -281
kernel/bpf/verifier.c
··· 4 4 * Copyright (c) 2018 Covalent IO, Inc. http://covalent.io 5 5 */ 6 6 #include <uapi/linux/btf.h> 7 + #include <linux/bpf-cgroup.h> 7 8 #include <linux/kernel.h> 8 9 #include <linux/types.h> 9 10 #include <linux/slab.h> ··· 442 441 type == PTR_TO_SOCK_COMMON; 443 442 } 444 443 445 - static bool reg_type_may_be_null(enum bpf_reg_type type) 446 - { 447 - return type == PTR_TO_MAP_VALUE_OR_NULL || 448 - type == PTR_TO_SOCKET_OR_NULL || 449 - type == PTR_TO_SOCK_COMMON_OR_NULL || 450 - type == PTR_TO_TCP_SOCK_OR_NULL || 451 - type == PTR_TO_BTF_ID_OR_NULL || 452 - type == PTR_TO_MEM_OR_NULL || 453 - type == PTR_TO_RDONLY_BUF_OR_NULL || 454 - type == PTR_TO_RDWR_BUF_OR_NULL; 455 - } 456 - 457 444 static bool reg_may_point_to_spin_lock(const struct bpf_reg_state *reg) 458 445 { 459 446 return reg->type == PTR_TO_MAP_VALUE && ··· 450 461 451 462 static bool reg_type_may_be_refcounted_or_null(enum bpf_reg_type type) 452 463 { 453 - return type == PTR_TO_SOCKET || 454 - type == PTR_TO_SOCKET_OR_NULL || 455 - type == PTR_TO_TCP_SOCK || 456 - type == PTR_TO_TCP_SOCK_OR_NULL || 457 - type == PTR_TO_MEM || 458 - type == PTR_TO_MEM_OR_NULL; 464 + return base_type(type) == PTR_TO_SOCKET || 465 + base_type(type) == PTR_TO_TCP_SOCK || 466 + base_type(type) == PTR_TO_MEM; 467 + } 468 + 469 + static bool type_is_rdonly_mem(u32 type) 470 + { 471 + return type & MEM_RDONLY; 459 472 } 460 473 461 474 static bool arg_type_may_be_refcounted(enum bpf_arg_type type) ··· 465 474 return type == ARG_PTR_TO_SOCK_COMMON; 466 475 } 467 476 468 - static bool arg_type_may_be_null(enum bpf_arg_type type) 477 + static bool type_may_be_null(u32 type) 469 478 { 470 - return type == ARG_PTR_TO_MAP_VALUE_OR_NULL || 471 - type == ARG_PTR_TO_MEM_OR_NULL || 472 - type == ARG_PTR_TO_CTX_OR_NULL || 473 - type == ARG_PTR_TO_SOCKET_OR_NULL || 474 - type == ARG_PTR_TO_ALLOC_MEM_OR_NULL || 475 - type == ARG_PTR_TO_STACK_OR_NULL; 479 + return type & PTR_MAYBE_NULL; 476 480 } 477 481 478 482 /* Determine whether the function releases some resources allocated by another ··· 527 541 insn->imm == BPF_CMPXCHG; 528 542 } 529 543 530 - /* string representation of 'enum bpf_reg_type' */ 531 - static const char * const reg_type_str[] = { 532 - [NOT_INIT] = "?", 533 - [SCALAR_VALUE] = "inv", 534 - [PTR_TO_CTX] = "ctx", 535 - [CONST_PTR_TO_MAP] = "map_ptr", 536 - [PTR_TO_MAP_VALUE] = "map_value", 537 - [PTR_TO_MAP_VALUE_OR_NULL] = "map_value_or_null", 538 - [PTR_TO_STACK] = "fp", 539 - [PTR_TO_PACKET] = "pkt", 540 - [PTR_TO_PACKET_META] = "pkt_meta", 541 - [PTR_TO_PACKET_END] = "pkt_end", 542 - [PTR_TO_FLOW_KEYS] = "flow_keys", 543 - [PTR_TO_SOCKET] = "sock", 544 - [PTR_TO_SOCKET_OR_NULL] = "sock_or_null", 545 - [PTR_TO_SOCK_COMMON] = "sock_common", 546 - [PTR_TO_SOCK_COMMON_OR_NULL] = "sock_common_or_null", 547 - [PTR_TO_TCP_SOCK] = "tcp_sock", 548 - [PTR_TO_TCP_SOCK_OR_NULL] = "tcp_sock_or_null", 549 - [PTR_TO_TP_BUFFER] = "tp_buffer", 550 - [PTR_TO_XDP_SOCK] = "xdp_sock", 551 - [PTR_TO_BTF_ID] = "ptr_", 552 - [PTR_TO_BTF_ID_OR_NULL] = "ptr_or_null_", 553 - [PTR_TO_PERCPU_BTF_ID] = "percpu_ptr_", 554 - [PTR_TO_MEM] = "mem", 555 - [PTR_TO_MEM_OR_NULL] = "mem_or_null", 556 - [PTR_TO_RDONLY_BUF] = "rdonly_buf", 557 - [PTR_TO_RDONLY_BUF_OR_NULL] = "rdonly_buf_or_null", 558 - [PTR_TO_RDWR_BUF] = "rdwr_buf", 559 - [PTR_TO_RDWR_BUF_OR_NULL] = "rdwr_buf_or_null", 560 - [PTR_TO_FUNC] = "func", 561 - [PTR_TO_MAP_KEY] = "map_key", 562 - }; 544 + /* string representation of 'enum bpf_reg_type' 545 + * 546 + * Note that reg_type_str() can not appear more than once in a single verbose() 547 + * statement. 548 + */ 549 + static const char *reg_type_str(struct bpf_verifier_env *env, 550 + enum bpf_reg_type type) 551 + { 552 + char postfix[16] = {0}, prefix[16] = {0}; 553 + static const char * const str[] = { 554 + [NOT_INIT] = "?", 555 + [SCALAR_VALUE] = "inv", 556 + [PTR_TO_CTX] = "ctx", 557 + [CONST_PTR_TO_MAP] = "map_ptr", 558 + [PTR_TO_MAP_VALUE] = "map_value", 559 + [PTR_TO_STACK] = "fp", 560 + [PTR_TO_PACKET] = "pkt", 561 + [PTR_TO_PACKET_META] = "pkt_meta", 562 + [PTR_TO_PACKET_END] = "pkt_end", 563 + [PTR_TO_FLOW_KEYS] = "flow_keys", 564 + [PTR_TO_SOCKET] = "sock", 565 + [PTR_TO_SOCK_COMMON] = "sock_common", 566 + [PTR_TO_TCP_SOCK] = "tcp_sock", 567 + [PTR_TO_TP_BUFFER] = "tp_buffer", 568 + [PTR_TO_XDP_SOCK] = "xdp_sock", 569 + [PTR_TO_BTF_ID] = "ptr_", 570 + [PTR_TO_PERCPU_BTF_ID] = "percpu_ptr_", 571 + [PTR_TO_MEM] = "mem", 572 + [PTR_TO_BUF] = "buf", 573 + [PTR_TO_FUNC] = "func", 574 + [PTR_TO_MAP_KEY] = "map_key", 575 + }; 576 + 577 + if (type & PTR_MAYBE_NULL) { 578 + if (base_type(type) == PTR_TO_BTF_ID || 579 + base_type(type) == PTR_TO_PERCPU_BTF_ID) 580 + strncpy(postfix, "or_null_", 16); 581 + else 582 + strncpy(postfix, "_or_null", 16); 583 + } 584 + 585 + if (type & MEM_RDONLY) 586 + strncpy(prefix, "rdonly_", 16); 587 + 588 + snprintf(env->type_str_buf, TYPE_STR_BUF_LEN, "%s%s%s", 589 + prefix, str[base_type(type)], postfix); 590 + return env->type_str_buf; 591 + } 563 592 564 593 static char slot_type_char[] = { 565 594 [STACK_INVALID] = '?', ··· 609 608 return btf_name_by_offset(btf, btf_type_by_id(btf, id)->name_off); 610 609 } 611 610 611 + static void mark_reg_scratched(struct bpf_verifier_env *env, u32 regno) 612 + { 613 + env->scratched_regs |= 1U << regno; 614 + } 615 + 616 + static void mark_stack_slot_scratched(struct bpf_verifier_env *env, u32 spi) 617 + { 618 + env->scratched_stack_slots |= 1UL << spi; 619 + } 620 + 621 + static bool reg_scratched(const struct bpf_verifier_env *env, u32 regno) 622 + { 623 + return (env->scratched_regs >> regno) & 1; 624 + } 625 + 626 + static bool stack_slot_scratched(const struct bpf_verifier_env *env, u64 regno) 627 + { 628 + return (env->scratched_stack_slots >> regno) & 1; 629 + } 630 + 631 + static bool verifier_state_scratched(const struct bpf_verifier_env *env) 632 + { 633 + return env->scratched_regs || env->scratched_stack_slots; 634 + } 635 + 636 + static void mark_verifier_state_clean(struct bpf_verifier_env *env) 637 + { 638 + env->scratched_regs = 0U; 639 + env->scratched_stack_slots = 0UL; 640 + } 641 + 642 + /* Used for printing the entire verifier state. */ 643 + static void mark_verifier_state_scratched(struct bpf_verifier_env *env) 644 + { 645 + env->scratched_regs = ~0U; 646 + env->scratched_stack_slots = ~0UL; 647 + } 648 + 612 649 /* The reg state of a pointer or a bounded scalar was saved when 613 650 * it was spilled to the stack. 614 651 */ ··· 662 623 } 663 624 664 625 static void print_verifier_state(struct bpf_verifier_env *env, 665 - const struct bpf_func_state *state) 626 + const struct bpf_func_state *state, 627 + bool print_all) 666 628 { 667 629 const struct bpf_reg_state *reg; 668 630 enum bpf_reg_type t; ··· 676 636 t = reg->type; 677 637 if (t == NOT_INIT) 678 638 continue; 639 + if (!print_all && !reg_scratched(env, i)) 640 + continue; 679 641 verbose(env, " R%d", i); 680 642 print_liveness(env, reg->live); 681 - verbose(env, "=%s", reg_type_str[t]); 643 + verbose(env, "=%s", reg_type_str(env, t)); 682 644 if (t == SCALAR_VALUE && reg->precise) 683 645 verbose(env, "P"); 684 646 if ((t == SCALAR_VALUE || t == PTR_TO_STACK) && ··· 688 646 /* reg->off should be 0 for SCALAR_VALUE */ 689 647 verbose(env, "%lld", reg->var_off.value + reg->off); 690 648 } else { 691 - if (t == PTR_TO_BTF_ID || 692 - t == PTR_TO_BTF_ID_OR_NULL || 693 - t == PTR_TO_PERCPU_BTF_ID) 649 + if (base_type(t) == PTR_TO_BTF_ID || 650 + base_type(t) == PTR_TO_PERCPU_BTF_ID) 694 651 verbose(env, "%s", kernel_type_name(reg->btf, reg->btf_id)); 695 652 verbose(env, "(id=%d", reg->id); 696 653 if (reg_type_may_be_refcounted_or_null(t)) ··· 698 657 verbose(env, ",off=%d", reg->off); 699 658 if (type_is_pkt_pointer(t)) 700 659 verbose(env, ",r=%d", reg->range); 701 - else if (t == CONST_PTR_TO_MAP || 702 - t == PTR_TO_MAP_KEY || 703 - t == PTR_TO_MAP_VALUE || 704 - t == PTR_TO_MAP_VALUE_OR_NULL) 660 + else if (base_type(t) == CONST_PTR_TO_MAP || 661 + base_type(t) == PTR_TO_MAP_KEY || 662 + base_type(t) == PTR_TO_MAP_VALUE) 705 663 verbose(env, ",ks=%d,vs=%d", 706 664 reg->map_ptr->key_size, 707 665 reg->map_ptr->value_size); ··· 765 725 types_buf[BPF_REG_SIZE] = 0; 766 726 if (!valid) 767 727 continue; 728 + if (!print_all && !stack_slot_scratched(env, i)) 729 + continue; 768 730 verbose(env, " fp%d", (-i - 1) * BPF_REG_SIZE); 769 731 print_liveness(env, state->stack[i].spilled_ptr.live); 770 732 if (is_spilled_reg(&state->stack[i])) { 771 733 reg = &state->stack[i].spilled_ptr; 772 734 t = reg->type; 773 - verbose(env, "=%s", reg_type_str[t]); 735 + verbose(env, "=%s", reg_type_str(env, t)); 774 736 if (t == SCALAR_VALUE && reg->precise) 775 737 verbose(env, "P"); 776 738 if (t == SCALAR_VALUE && tnum_is_const(reg->var_off)) ··· 792 750 if (state->in_async_callback_fn) 793 751 verbose(env, " async_cb"); 794 752 verbose(env, "\n"); 753 + mark_verifier_state_clean(env); 754 + } 755 + 756 + static inline u32 vlog_alignment(u32 pos) 757 + { 758 + return round_up(max(pos + BPF_LOG_MIN_ALIGNMENT / 2, BPF_LOG_ALIGNMENT), 759 + BPF_LOG_MIN_ALIGNMENT) - pos - 1; 760 + } 761 + 762 + static void print_insn_state(struct bpf_verifier_env *env, 763 + const struct bpf_func_state *state) 764 + { 765 + if (env->prev_log_len && env->prev_log_len == env->log.len_used) { 766 + /* remove new line character */ 767 + bpf_vlog_reset(&env->log, env->prev_log_len - 1); 768 + verbose(env, "%*c;", vlog_alignment(env->prev_insn_print_len), ' '); 769 + } else { 770 + verbose(env, "%d:", env->insn_idx); 771 + } 772 + print_verifier_state(env, state, false); 795 773 } 796 774 797 775 /* copy array src of length n * size bytes to dst. dst is reallocated if it's too ··· 1205 1143 1206 1144 static void mark_ptr_not_null_reg(struct bpf_reg_state *reg) 1207 1145 { 1208 - switch (reg->type) { 1209 - case PTR_TO_MAP_VALUE_OR_NULL: { 1146 + if (base_type(reg->type) == PTR_TO_MAP_VALUE) { 1210 1147 const struct bpf_map *map = reg->map_ptr; 1211 1148 1212 1149 if (map->inner_map_meta) { ··· 1224 1163 } else { 1225 1164 reg->type = PTR_TO_MAP_VALUE; 1226 1165 } 1227 - break; 1166 + return; 1228 1167 } 1229 - case PTR_TO_SOCKET_OR_NULL: 1230 - reg->type = PTR_TO_SOCKET; 1231 - break; 1232 - case PTR_TO_SOCK_COMMON_OR_NULL: 1233 - reg->type = PTR_TO_SOCK_COMMON; 1234 - break; 1235 - case PTR_TO_TCP_SOCK_OR_NULL: 1236 - reg->type = PTR_TO_TCP_SOCK; 1237 - break; 1238 - case PTR_TO_BTF_ID_OR_NULL: 1239 - reg->type = PTR_TO_BTF_ID; 1240 - break; 1241 - case PTR_TO_MEM_OR_NULL: 1242 - reg->type = PTR_TO_MEM; 1243 - break; 1244 - case PTR_TO_RDONLY_BUF_OR_NULL: 1245 - reg->type = PTR_TO_RDONLY_BUF; 1246 - break; 1247 - case PTR_TO_RDWR_BUF_OR_NULL: 1248 - reg->type = PTR_TO_RDWR_BUF; 1249 - break; 1250 - default: 1251 - WARN_ONCE(1, "unknown nullable register type"); 1252 - } 1168 + 1169 + reg->type &= ~PTR_MAYBE_NULL; 1253 1170 } 1254 1171 1255 1172 static bool reg_is_pkt_pointer(const struct bpf_reg_state *reg) ··· 1585 1546 state->frameno = frameno; 1586 1547 state->subprogno = subprogno; 1587 1548 init_reg_state(env, state); 1549 + mark_verifier_state_scratched(env); 1588 1550 } 1589 1551 1590 1552 /* Similar to push_stack(), but for async callbacks */ ··· 2089 2049 break; 2090 2050 if (parent->live & REG_LIVE_DONE) { 2091 2051 verbose(env, "verifier BUG type %s var_off %lld off %d\n", 2092 - reg_type_str[parent->type], 2052 + reg_type_str(env, parent->type), 2093 2053 parent->var_off.value, parent->off); 2094 2054 return -EFAULT; 2095 2055 } ··· 2273 2233 return -EINVAL; 2274 2234 } 2275 2235 2236 + mark_reg_scratched(env, regno); 2237 + 2276 2238 reg = &regs[regno]; 2277 2239 rw64 = is_reg64(env, insn, regno, reg, t); 2278 2240 if (t == SRC_OP) { ··· 2379 2337 2380 2338 if (insn->code == 0) 2381 2339 return 0; 2382 - if (env->log.level & BPF_LOG_LEVEL) { 2340 + if (env->log.level & BPF_LOG_LEVEL2) { 2383 2341 verbose(env, "regs=%x stack=%llx before ", *reg_mask, *stack_mask); 2384 2342 verbose(env, "%d: ", idx); 2385 2343 print_bpf_insn(&cbs, insn, env->allow_ptr_leaks); ··· 2633 2591 DECLARE_BITMAP(mask, 64); 2634 2592 u32 history = st->jmp_history_cnt; 2635 2593 2636 - if (env->log.level & BPF_LOG_LEVEL) 2594 + if (env->log.level & BPF_LOG_LEVEL2) 2637 2595 verbose(env, "last_idx %d first_idx %d\n", last_idx, first_idx); 2638 2596 for (i = last_idx;;) { 2639 2597 if (skip_first) { ··· 2720 2678 new_marks = true; 2721 2679 reg->precise = true; 2722 2680 } 2723 - if (env->log.level & BPF_LOG_LEVEL) { 2724 - print_verifier_state(env, func); 2725 - verbose(env, "parent %s regs=%x stack=%llx marks\n", 2681 + if (env->log.level & BPF_LOG_LEVEL2) { 2682 + verbose(env, "parent %s regs=%x stack=%llx marks:", 2726 2683 new_marks ? "didn't have" : "already had", 2727 2684 reg_mask, stack_mask); 2685 + print_verifier_state(env, func, true); 2728 2686 } 2729 2687 2730 2688 if (!reg_mask && !stack_mask) ··· 2750 2708 2751 2709 static bool is_spillable_regtype(enum bpf_reg_type type) 2752 2710 { 2753 - switch (type) { 2711 + switch (base_type(type)) { 2754 2712 case PTR_TO_MAP_VALUE: 2755 - case PTR_TO_MAP_VALUE_OR_NULL: 2756 2713 case PTR_TO_STACK: 2757 2714 case PTR_TO_CTX: 2758 2715 case PTR_TO_PACKET: ··· 2760 2719 case PTR_TO_FLOW_KEYS: 2761 2720 case CONST_PTR_TO_MAP: 2762 2721 case PTR_TO_SOCKET: 2763 - case PTR_TO_SOCKET_OR_NULL: 2764 2722 case PTR_TO_SOCK_COMMON: 2765 - case PTR_TO_SOCK_COMMON_OR_NULL: 2766 2723 case PTR_TO_TCP_SOCK: 2767 - case PTR_TO_TCP_SOCK_OR_NULL: 2768 2724 case PTR_TO_XDP_SOCK: 2769 2725 case PTR_TO_BTF_ID: 2770 - case PTR_TO_BTF_ID_OR_NULL: 2771 - case PTR_TO_RDONLY_BUF: 2772 - case PTR_TO_RDONLY_BUF_OR_NULL: 2773 - case PTR_TO_RDWR_BUF: 2774 - case PTR_TO_RDWR_BUF_OR_NULL: 2726 + case PTR_TO_BUF: 2775 2727 case PTR_TO_PERCPU_BTF_ID: 2776 2728 case PTR_TO_MEM: 2777 - case PTR_TO_MEM_OR_NULL: 2778 2729 case PTR_TO_FUNC: 2779 2730 case PTR_TO_MAP_KEY: 2780 2731 return true; ··· 2871 2838 env->insn_aux_data[insn_idx].sanitize_stack_spill = true; 2872 2839 } 2873 2840 2841 + mark_stack_slot_scratched(env, spi); 2874 2842 if (reg && !(off % BPF_REG_SIZE) && register_is_bounded(reg) && 2875 2843 !register_is_null(reg) && env->bpf_capable) { 2876 2844 if (dst_reg != BPF_REG_FP) { ··· 2993 2959 slot = -i - 1; 2994 2960 spi = slot / BPF_REG_SIZE; 2995 2961 stype = &state->stack[spi].slot_type[slot % BPF_REG_SIZE]; 2962 + mark_stack_slot_scratched(env, spi); 2996 2963 2997 2964 if (!env->allow_ptr_leaks 2998 2965 && *stype != NOT_INIT ··· 3410 3375 /* We may have adjusted the register pointing to memory region, so we 3411 3376 * need to try adding each of min_value and max_value to off 3412 3377 * to make sure our theoretical access will be safe. 3413 - */ 3414 - if (env->log.level & BPF_LOG_LEVEL) 3415 - print_verifier_state(env, state); 3416 - 3417 - /* The minimum value is only important with signed 3378 + * 3379 + * The minimum value is only important with signed 3418 3380 * comparisons where we can't assume the floor of a 3419 3381 * value is 0. If we are using signed variables for our 3420 3382 * index'es we need to make sure that whatever we use ··· 3606 3574 */ 3607 3575 *reg_type = info.reg_type; 3608 3576 3609 - if (*reg_type == PTR_TO_BTF_ID || *reg_type == PTR_TO_BTF_ID_OR_NULL) { 3577 + if (base_type(*reg_type) == PTR_TO_BTF_ID) { 3610 3578 *btf = info.btf; 3611 3579 *btf_id = info.btf_id; 3612 3580 } else { ··· 3674 3642 } 3675 3643 3676 3644 verbose(env, "R%d invalid %s access off=%d size=%d\n", 3677 - regno, reg_type_str[reg->type], off, size); 3645 + regno, reg_type_str(env, reg->type), off, size); 3678 3646 3679 3647 return -EACCES; 3680 3648 } ··· 4401 4369 mark_reg_unknown(env, regs, value_regno); 4402 4370 } 4403 4371 } 4404 - } else if (reg->type == PTR_TO_MEM) { 4372 + } else if (base_type(reg->type) == PTR_TO_MEM) { 4373 + bool rdonly_mem = type_is_rdonly_mem(reg->type); 4374 + 4375 + if (type_may_be_null(reg->type)) { 4376 + verbose(env, "R%d invalid mem access '%s'\n", regno, 4377 + reg_type_str(env, reg->type)); 4378 + return -EACCES; 4379 + } 4380 + 4381 + if (t == BPF_WRITE && rdonly_mem) { 4382 + verbose(env, "R%d cannot write into %s\n", 4383 + regno, reg_type_str(env, reg->type)); 4384 + return -EACCES; 4385 + } 4386 + 4405 4387 if (t == BPF_WRITE && value_regno >= 0 && 4406 4388 is_pointer_value(env, value_regno)) { 4407 4389 verbose(env, "R%d leaks addr into mem\n", value_regno); 4408 4390 return -EACCES; 4409 4391 } 4392 + 4410 4393 err = check_mem_region_access(env, regno, off, size, 4411 4394 reg->mem_size, false); 4412 - if (!err && t == BPF_READ && value_regno >= 0) 4395 + if (!err && value_regno >= 0 && (t == BPF_READ || rdonly_mem)) 4413 4396 mark_reg_unknown(env, regs, value_regno); 4414 4397 } else if (reg->type == PTR_TO_CTX) { 4415 4398 enum bpf_reg_type reg_type = SCALAR_VALUE; ··· 4454 4407 } else { 4455 4408 mark_reg_known_zero(env, regs, 4456 4409 value_regno); 4457 - if (reg_type_may_be_null(reg_type)) 4410 + if (type_may_be_null(reg_type)) 4458 4411 regs[value_regno].id = ++env->id_gen; 4459 4412 /* A load of ctx field could have different 4460 4413 * actual load size with the one encoded in the ··· 4462 4415 * a sub-register. 4463 4416 */ 4464 4417 regs[value_regno].subreg_def = DEF_NOT_SUBREG; 4465 - if (reg_type == PTR_TO_BTF_ID || 4466 - reg_type == PTR_TO_BTF_ID_OR_NULL) { 4418 + if (base_type(reg_type) == PTR_TO_BTF_ID) { 4467 4419 regs[value_regno].btf = btf; 4468 4420 regs[value_regno].btf_id = btf_id; 4469 4421 } ··· 4515 4469 } else if (type_is_sk_pointer(reg->type)) { 4516 4470 if (t == BPF_WRITE) { 4517 4471 verbose(env, "R%d cannot write into %s\n", 4518 - regno, reg_type_str[reg->type]); 4472 + regno, reg_type_str(env, reg->type)); 4519 4473 return -EACCES; 4520 4474 } 4521 4475 err = check_sock_access(env, insn_idx, regno, off, size, t); ··· 4531 4485 } else if (reg->type == CONST_PTR_TO_MAP) { 4532 4486 err = check_ptr_to_map_access(env, regs, regno, off, size, t, 4533 4487 value_regno); 4534 - } else if (reg->type == PTR_TO_RDONLY_BUF) { 4535 - if (t == BPF_WRITE) { 4536 - verbose(env, "R%d cannot write into %s\n", 4537 - regno, reg_type_str[reg->type]); 4538 - return -EACCES; 4488 + } else if (base_type(reg->type) == PTR_TO_BUF) { 4489 + bool rdonly_mem = type_is_rdonly_mem(reg->type); 4490 + const char *buf_info; 4491 + u32 *max_access; 4492 + 4493 + if (rdonly_mem) { 4494 + if (t == BPF_WRITE) { 4495 + verbose(env, "R%d cannot write into %s\n", 4496 + regno, reg_type_str(env, reg->type)); 4497 + return -EACCES; 4498 + } 4499 + buf_info = "rdonly"; 4500 + max_access = &env->prog->aux->max_rdonly_access; 4501 + } else { 4502 + buf_info = "rdwr"; 4503 + max_access = &env->prog->aux->max_rdwr_access; 4539 4504 } 4505 + 4540 4506 err = check_buffer_access(env, reg, regno, off, size, false, 4541 - "rdonly", 4542 - &env->prog->aux->max_rdonly_access); 4543 - if (!err && value_regno >= 0) 4544 - mark_reg_unknown(env, regs, value_regno); 4545 - } else if (reg->type == PTR_TO_RDWR_BUF) { 4546 - err = check_buffer_access(env, reg, regno, off, size, false, 4547 - "rdwr", 4548 - &env->prog->aux->max_rdwr_access); 4549 - if (!err && t == BPF_READ && value_regno >= 0) 4507 + buf_info, max_access); 4508 + 4509 + if (!err && value_regno >= 0 && (rdonly_mem || t == BPF_READ)) 4550 4510 mark_reg_unknown(env, regs, value_regno); 4551 4511 } else { 4552 4512 verbose(env, "R%d invalid mem access '%s'\n", regno, 4553 - reg_type_str[reg->type]); 4513 + reg_type_str(env, reg->type)); 4554 4514 return -EACCES; 4555 4515 } 4556 4516 ··· 4630 4578 is_sk_reg(env, insn->dst_reg)) { 4631 4579 verbose(env, "BPF_ATOMIC stores into R%d %s is not allowed\n", 4632 4580 insn->dst_reg, 4633 - reg_type_str[reg_state(env, insn->dst_reg)->type]); 4581 + reg_type_str(env, reg_state(env, insn->dst_reg)->type)); 4634 4582 return -EACCES; 4635 4583 } 4636 4584 ··· 4813 4761 struct bpf_call_arg_meta *meta) 4814 4762 { 4815 4763 struct bpf_reg_state *regs = cur_regs(env), *reg = &regs[regno]; 4764 + const char *buf_info; 4765 + u32 *max_access; 4816 4766 4817 - switch (reg->type) { 4767 + switch (base_type(reg->type)) { 4818 4768 case PTR_TO_PACKET: 4819 4769 case PTR_TO_PACKET_META: 4820 4770 return check_packet_access(env, regno, reg->off, access_size, ··· 4835 4781 return check_mem_region_access(env, regno, reg->off, 4836 4782 access_size, reg->mem_size, 4837 4783 zero_size_allowed); 4838 - case PTR_TO_RDONLY_BUF: 4839 - if (meta && meta->raw_mode) 4840 - return -EACCES; 4784 + case PTR_TO_BUF: 4785 + if (type_is_rdonly_mem(reg->type)) { 4786 + if (meta && meta->raw_mode) 4787 + return -EACCES; 4788 + 4789 + buf_info = "rdonly"; 4790 + max_access = &env->prog->aux->max_rdonly_access; 4791 + } else { 4792 + buf_info = "rdwr"; 4793 + max_access = &env->prog->aux->max_rdwr_access; 4794 + } 4841 4795 return check_buffer_access(env, reg, regno, reg->off, 4842 4796 access_size, zero_size_allowed, 4843 - "rdonly", 4844 - &env->prog->aux->max_rdonly_access); 4845 - case PTR_TO_RDWR_BUF: 4846 - return check_buffer_access(env, reg, regno, reg->off, 4847 - access_size, zero_size_allowed, 4848 - "rdwr", 4849 - &env->prog->aux->max_rdwr_access); 4797 + buf_info, max_access); 4850 4798 case PTR_TO_STACK: 4851 4799 return check_stack_range_initialized( 4852 4800 env, ··· 4860 4804 register_is_null(reg)) 4861 4805 return 0; 4862 4806 4863 - verbose(env, "R%d type=%s expected=%s\n", regno, 4864 - reg_type_str[reg->type], 4865 - reg_type_str[PTR_TO_STACK]); 4807 + verbose(env, "R%d type=%s ", regno, 4808 + reg_type_str(env, reg->type)); 4809 + verbose(env, "expected=%s\n", reg_type_str(env, PTR_TO_STACK)); 4866 4810 return -EACCES; 4867 4811 } 4868 4812 } ··· 4873 4817 if (register_is_null(reg)) 4874 4818 return 0; 4875 4819 4876 - if (reg_type_may_be_null(reg->type)) { 4820 + if (type_may_be_null(reg->type)) { 4877 4821 /* Assuming that the register contains a value check if the memory 4878 4822 * access is safe. Temporarily save and restore the register's state as 4879 4823 * the conversion shouldn't be visible to a caller. ··· 5021 4965 5022 4966 static bool arg_type_is_mem_ptr(enum bpf_arg_type type) 5023 4967 { 5024 - return type == ARG_PTR_TO_MEM || 5025 - type == ARG_PTR_TO_MEM_OR_NULL || 5026 - type == ARG_PTR_TO_UNINIT_MEM; 4968 + return base_type(type) == ARG_PTR_TO_MEM || 4969 + base_type(type) == ARG_PTR_TO_UNINIT_MEM; 5027 4970 } 5028 4971 5029 4972 static bool arg_type_is_mem_size(enum bpf_arg_type type) ··· 5127 5072 PTR_TO_MAP_KEY, 5128 5073 PTR_TO_MAP_VALUE, 5129 5074 PTR_TO_MEM, 5130 - PTR_TO_RDONLY_BUF, 5131 - PTR_TO_RDWR_BUF, 5075 + PTR_TO_BUF, 5132 5076 }, 5133 5077 }; 5134 5078 ··· 5158 5104 [ARG_PTR_TO_MAP_KEY] = &map_key_value_types, 5159 5105 [ARG_PTR_TO_MAP_VALUE] = &map_key_value_types, 5160 5106 [ARG_PTR_TO_UNINIT_MAP_VALUE] = &map_key_value_types, 5161 - [ARG_PTR_TO_MAP_VALUE_OR_NULL] = &map_key_value_types, 5162 5107 [ARG_CONST_SIZE] = &scalar_types, 5163 5108 [ARG_CONST_SIZE_OR_ZERO] = &scalar_types, 5164 5109 [ARG_CONST_ALLOC_SIZE_OR_ZERO] = &scalar_types, 5165 5110 [ARG_CONST_MAP_PTR] = &const_map_ptr_types, 5166 5111 [ARG_PTR_TO_CTX] = &context_types, 5167 - [ARG_PTR_TO_CTX_OR_NULL] = &context_types, 5168 5112 [ARG_PTR_TO_SOCK_COMMON] = &sock_types, 5169 5113 #ifdef CONFIG_NET 5170 5114 [ARG_PTR_TO_BTF_ID_SOCK_COMMON] = &btf_id_sock_common_types, 5171 5115 #endif 5172 5116 [ARG_PTR_TO_SOCKET] = &fullsock_types, 5173 - [ARG_PTR_TO_SOCKET_OR_NULL] = &fullsock_types, 5174 5117 [ARG_PTR_TO_BTF_ID] = &btf_ptr_types, 5175 5118 [ARG_PTR_TO_SPIN_LOCK] = &spin_lock_types, 5176 5119 [ARG_PTR_TO_MEM] = &mem_types, 5177 - [ARG_PTR_TO_MEM_OR_NULL] = &mem_types, 5178 5120 [ARG_PTR_TO_UNINIT_MEM] = &mem_types, 5179 5121 [ARG_PTR_TO_ALLOC_MEM] = &alloc_mem_types, 5180 - [ARG_PTR_TO_ALLOC_MEM_OR_NULL] = &alloc_mem_types, 5181 5122 [ARG_PTR_TO_INT] = &int_ptr_types, 5182 5123 [ARG_PTR_TO_LONG] = &int_ptr_types, 5183 5124 [ARG_PTR_TO_PERCPU_BTF_ID] = &percpu_btf_ptr_types, 5184 5125 [ARG_PTR_TO_FUNC] = &func_ptr_types, 5185 - [ARG_PTR_TO_STACK_OR_NULL] = &stack_ptr_types, 5126 + [ARG_PTR_TO_STACK] = &stack_ptr_types, 5186 5127 [ARG_PTR_TO_CONST_STR] = &const_str_ptr_types, 5187 5128 [ARG_PTR_TO_TIMER] = &timer_types, 5188 5129 }; ··· 5191 5142 const struct bpf_reg_types *compatible; 5192 5143 int i, j; 5193 5144 5194 - compatible = compatible_reg_types[arg_type]; 5145 + compatible = compatible_reg_types[base_type(arg_type)]; 5195 5146 if (!compatible) { 5196 5147 verbose(env, "verifier internal error: unsupported arg type %d\n", arg_type); 5197 5148 return -EFAULT; 5198 5149 } 5150 + 5151 + /* ARG_PTR_TO_MEM + RDONLY is compatible with PTR_TO_MEM and PTR_TO_MEM + RDONLY, 5152 + * but ARG_PTR_TO_MEM is compatible only with PTR_TO_MEM and NOT with PTR_TO_MEM + RDONLY 5153 + * 5154 + * Same for MAYBE_NULL: 5155 + * 5156 + * ARG_PTR_TO_MEM + MAYBE_NULL is compatible with PTR_TO_MEM and PTR_TO_MEM + MAYBE_NULL, 5157 + * but ARG_PTR_TO_MEM is compatible only with PTR_TO_MEM but NOT with PTR_TO_MEM + MAYBE_NULL 5158 + * 5159 + * Therefore we fold these flags depending on the arg_type before comparison. 5160 + */ 5161 + if (arg_type & MEM_RDONLY) 5162 + type &= ~MEM_RDONLY; 5163 + if (arg_type & PTR_MAYBE_NULL) 5164 + type &= ~PTR_MAYBE_NULL; 5199 5165 5200 5166 for (i = 0; i < ARRAY_SIZE(compatible->types); i++) { 5201 5167 expected = compatible->types[i]; ··· 5221 5157 goto found; 5222 5158 } 5223 5159 5224 - verbose(env, "R%d type=%s expected=", regno, reg_type_str[type]); 5160 + verbose(env, "R%d type=%s expected=", regno, reg_type_str(env, reg->type)); 5225 5161 for (j = 0; j + 1 < i; j++) 5226 - verbose(env, "%s, ", reg_type_str[compatible->types[j]]); 5227 - verbose(env, "%s\n", reg_type_str[compatible->types[j]]); 5162 + verbose(env, "%s, ", reg_type_str(env, compatible->types[j])); 5163 + verbose(env, "%s\n", reg_type_str(env, compatible->types[j])); 5228 5164 return -EACCES; 5229 5165 5230 5166 found: 5231 - if (type == PTR_TO_BTF_ID) { 5167 + if (reg->type == PTR_TO_BTF_ID) { 5232 5168 if (!arg_btf_id) { 5233 5169 if (!compatible->btf_id) { 5234 5170 verbose(env, "verifier internal error: missing arg compatible BTF ID\n"); ··· 5287 5223 return -EACCES; 5288 5224 } 5289 5225 5290 - if (arg_type == ARG_PTR_TO_MAP_VALUE || 5291 - arg_type == ARG_PTR_TO_UNINIT_MAP_VALUE || 5292 - arg_type == ARG_PTR_TO_MAP_VALUE_OR_NULL) { 5226 + if (base_type(arg_type) == ARG_PTR_TO_MAP_VALUE || 5227 + base_type(arg_type) == ARG_PTR_TO_UNINIT_MAP_VALUE) { 5293 5228 err = resolve_map_arg_type(env, meta, &arg_type); 5294 5229 if (err) 5295 5230 return err; 5296 5231 } 5297 5232 5298 - if (register_is_null(reg) && arg_type_may_be_null(arg_type)) 5233 + if (register_is_null(reg) && type_may_be_null(arg_type)) 5299 5234 /* A NULL register has a SCALAR_VALUE type, so skip 5300 5235 * type checking. 5301 5236 */ ··· 5363 5300 err = check_helper_mem_access(env, regno, 5364 5301 meta->map_ptr->key_size, false, 5365 5302 NULL); 5366 - } else if (arg_type == ARG_PTR_TO_MAP_VALUE || 5367 - (arg_type == ARG_PTR_TO_MAP_VALUE_OR_NULL && 5368 - !register_is_null(reg)) || 5369 - arg_type == ARG_PTR_TO_UNINIT_MAP_VALUE) { 5303 + } else if (base_type(arg_type) == ARG_PTR_TO_MAP_VALUE || 5304 + base_type(arg_type) == ARG_PTR_TO_UNINIT_MAP_VALUE) { 5305 + if (type_may_be_null(arg_type) && register_is_null(reg)) 5306 + return 0; 5307 + 5370 5308 /* bpf_map_xxx(..., map_ptr, ..., value) call: 5371 5309 * check [value, value + map->value_size) validity 5372 5310 */ ··· 6089 6025 6090 6026 if (env->log.level & BPF_LOG_LEVEL) { 6091 6027 verbose(env, "caller:\n"); 6092 - print_verifier_state(env, caller); 6028 + print_verifier_state(env, caller, true); 6093 6029 verbose(env, "callee:\n"); 6094 - print_verifier_state(env, callee); 6030 + print_verifier_state(env, callee, true); 6095 6031 } 6096 6032 return 0; 6097 6033 } ··· 6306 6242 *insn_idx = callee->callsite + 1; 6307 6243 if (env->log.level & BPF_LOG_LEVEL) { 6308 6244 verbose(env, "returning from callee:\n"); 6309 - print_verifier_state(env, callee); 6245 + print_verifier_state(env, callee, true); 6310 6246 verbose(env, "to caller at %d:\n", *insn_idx); 6311 - print_verifier_state(env, caller); 6247 + print_verifier_state(env, caller, true); 6312 6248 } 6313 6249 /* clear everything in the callee */ 6314 6250 free_func_state(callee); ··· 6474 6410 6475 6411 static int check_get_func_ip(struct bpf_verifier_env *env) 6476 6412 { 6477 - enum bpf_attach_type eatype = env->prog->expected_attach_type; 6478 6413 enum bpf_prog_type type = resolve_prog_type(env->prog); 6479 6414 int func_id = BPF_FUNC_get_func_ip; 6480 6415 6481 6416 if (type == BPF_PROG_TYPE_TRACING) { 6482 - if (eatype != BPF_TRACE_FENTRY && eatype != BPF_TRACE_FEXIT && 6483 - eatype != BPF_MODIFY_RETURN) { 6417 + if (!bpf_prog_has_trampoline(env->prog)) { 6484 6418 verbose(env, "func %s#%d supported only for fentry/fexit/fmod_ret programs\n", 6485 6419 func_id_name(func_id), func_id); 6486 6420 return -ENOTSUPP; ··· 6497 6435 int *insn_idx_p) 6498 6436 { 6499 6437 const struct bpf_func_proto *fn = NULL; 6438 + enum bpf_return_type ret_type; 6439 + enum bpf_type_flag ret_flag; 6500 6440 struct bpf_reg_state *regs; 6501 6441 struct bpf_call_arg_meta meta; 6502 6442 int insn_idx = *insn_idx_p; ··· 6638 6574 regs[BPF_REG_0].subreg_def = DEF_NOT_SUBREG; 6639 6575 6640 6576 /* update return register (already marked as written above) */ 6641 - if (fn->ret_type == RET_INTEGER) { 6577 + ret_type = fn->ret_type; 6578 + ret_flag = type_flag(fn->ret_type); 6579 + if (ret_type == RET_INTEGER) { 6642 6580 /* sets type to SCALAR_VALUE */ 6643 6581 mark_reg_unknown(env, regs, BPF_REG_0); 6644 - } else if (fn->ret_type == RET_VOID) { 6582 + } else if (ret_type == RET_VOID) { 6645 6583 regs[BPF_REG_0].type = NOT_INIT; 6646 - } else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL || 6647 - fn->ret_type == RET_PTR_TO_MAP_VALUE) { 6584 + } else if (base_type(ret_type) == RET_PTR_TO_MAP_VALUE) { 6648 6585 /* There is no offset yet applied, variable or fixed */ 6649 6586 mark_reg_known_zero(env, regs, BPF_REG_0); 6650 6587 /* remember map_ptr, so that check_map_access() ··· 6659 6594 } 6660 6595 regs[BPF_REG_0].map_ptr = meta.map_ptr; 6661 6596 regs[BPF_REG_0].map_uid = meta.map_uid; 6662 - if (fn->ret_type == RET_PTR_TO_MAP_VALUE) { 6663 - regs[BPF_REG_0].type = PTR_TO_MAP_VALUE; 6664 - if (map_value_has_spin_lock(meta.map_ptr)) 6665 - regs[BPF_REG_0].id = ++env->id_gen; 6666 - } else { 6667 - regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL; 6597 + regs[BPF_REG_0].type = PTR_TO_MAP_VALUE | ret_flag; 6598 + if (!type_may_be_null(ret_type) && 6599 + map_value_has_spin_lock(meta.map_ptr)) { 6600 + regs[BPF_REG_0].id = ++env->id_gen; 6668 6601 } 6669 - } else if (fn->ret_type == RET_PTR_TO_SOCKET_OR_NULL) { 6602 + } else if (base_type(ret_type) == RET_PTR_TO_SOCKET) { 6670 6603 mark_reg_known_zero(env, regs, BPF_REG_0); 6671 - regs[BPF_REG_0].type = PTR_TO_SOCKET_OR_NULL; 6672 - } else if (fn->ret_type == RET_PTR_TO_SOCK_COMMON_OR_NULL) { 6604 + regs[BPF_REG_0].type = PTR_TO_SOCKET | ret_flag; 6605 + } else if (base_type(ret_type) == RET_PTR_TO_SOCK_COMMON) { 6673 6606 mark_reg_known_zero(env, regs, BPF_REG_0); 6674 - regs[BPF_REG_0].type = PTR_TO_SOCK_COMMON_OR_NULL; 6675 - } else if (fn->ret_type == RET_PTR_TO_TCP_SOCK_OR_NULL) { 6607 + regs[BPF_REG_0].type = PTR_TO_SOCK_COMMON | ret_flag; 6608 + } else if (base_type(ret_type) == RET_PTR_TO_TCP_SOCK) { 6676 6609 mark_reg_known_zero(env, regs, BPF_REG_0); 6677 - regs[BPF_REG_0].type = PTR_TO_TCP_SOCK_OR_NULL; 6678 - } else if (fn->ret_type == RET_PTR_TO_ALLOC_MEM_OR_NULL) { 6610 + regs[BPF_REG_0].type = PTR_TO_TCP_SOCK | ret_flag; 6611 + } else if (base_type(ret_type) == RET_PTR_TO_ALLOC_MEM) { 6679 6612 mark_reg_known_zero(env, regs, BPF_REG_0); 6680 - regs[BPF_REG_0].type = PTR_TO_MEM_OR_NULL; 6613 + regs[BPF_REG_0].type = PTR_TO_MEM | ret_flag; 6681 6614 regs[BPF_REG_0].mem_size = meta.mem_size; 6682 - } else if (fn->ret_type == RET_PTR_TO_MEM_OR_BTF_ID_OR_NULL || 6683 - fn->ret_type == RET_PTR_TO_MEM_OR_BTF_ID) { 6615 + } else if (base_type(ret_type) == RET_PTR_TO_MEM_OR_BTF_ID) { 6684 6616 const struct btf_type *t; 6685 6617 6686 6618 mark_reg_known_zero(env, regs, BPF_REG_0); ··· 6695 6633 tname, PTR_ERR(ret)); 6696 6634 return -EINVAL; 6697 6635 } 6698 - regs[BPF_REG_0].type = 6699 - fn->ret_type == RET_PTR_TO_MEM_OR_BTF_ID ? 6700 - PTR_TO_MEM : PTR_TO_MEM_OR_NULL; 6636 + regs[BPF_REG_0].type = PTR_TO_MEM | ret_flag; 6701 6637 regs[BPF_REG_0].mem_size = tsize; 6702 6638 } else { 6703 - regs[BPF_REG_0].type = 6704 - fn->ret_type == RET_PTR_TO_MEM_OR_BTF_ID ? 6705 - PTR_TO_BTF_ID : PTR_TO_BTF_ID_OR_NULL; 6639 + /* MEM_RDONLY may be carried from ret_flag, but it 6640 + * doesn't apply on PTR_TO_BTF_ID. Fold it, otherwise 6641 + * it will confuse the check of PTR_TO_BTF_ID in 6642 + * check_mem_access(). 6643 + */ 6644 + ret_flag &= ~MEM_RDONLY; 6645 + 6646 + regs[BPF_REG_0].type = PTR_TO_BTF_ID | ret_flag; 6706 6647 regs[BPF_REG_0].btf = meta.ret_btf; 6707 6648 regs[BPF_REG_0].btf_id = meta.ret_btf_id; 6708 6649 } 6709 - } else if (fn->ret_type == RET_PTR_TO_BTF_ID_OR_NULL || 6710 - fn->ret_type == RET_PTR_TO_BTF_ID) { 6650 + } else if (base_type(ret_type) == RET_PTR_TO_BTF_ID) { 6711 6651 int ret_btf_id; 6712 6652 6713 6653 mark_reg_known_zero(env, regs, BPF_REG_0); 6714 - regs[BPF_REG_0].type = fn->ret_type == RET_PTR_TO_BTF_ID ? 6715 - PTR_TO_BTF_ID : 6716 - PTR_TO_BTF_ID_OR_NULL; 6654 + regs[BPF_REG_0].type = PTR_TO_BTF_ID | ret_flag; 6717 6655 ret_btf_id = *fn->ret_btf_id; 6718 6656 if (ret_btf_id == 0) { 6719 - verbose(env, "invalid return type %d of func %s#%d\n", 6720 - fn->ret_type, func_id_name(func_id), func_id); 6657 + verbose(env, "invalid return type %u of func %s#%d\n", 6658 + base_type(ret_type), func_id_name(func_id), 6659 + func_id); 6721 6660 return -EINVAL; 6722 6661 } 6723 6662 /* current BPF helper definitions are only coming from ··· 6727 6664 regs[BPF_REG_0].btf = btf_vmlinux; 6728 6665 regs[BPF_REG_0].btf_id = ret_btf_id; 6729 6666 } else { 6730 - verbose(env, "unknown return type %d of func %s#%d\n", 6731 - fn->ret_type, func_id_name(func_id), func_id); 6667 + verbose(env, "unknown return type %u of func %s#%d\n", 6668 + base_type(ret_type), func_id_name(func_id), func_id); 6732 6669 return -EINVAL; 6733 6670 } 6734 6671 6735 - if (reg_type_may_be_null(regs[BPF_REG_0].type)) 6672 + if (type_may_be_null(regs[BPF_REG_0].type)) 6736 6673 regs[BPF_REG_0].id = ++env->id_gen; 6737 6674 6738 6675 if (is_ptr_cast_function(func_id)) { ··· 6941 6878 6942 6879 if (known && (val >= BPF_MAX_VAR_OFF || val <= -BPF_MAX_VAR_OFF)) { 6943 6880 verbose(env, "math between %s pointer and %lld is not allowed\n", 6944 - reg_type_str[type], val); 6881 + reg_type_str(env, type), val); 6945 6882 return false; 6946 6883 } 6947 6884 6948 6885 if (reg->off >= BPF_MAX_VAR_OFF || reg->off <= -BPF_MAX_VAR_OFF) { 6949 6886 verbose(env, "%s pointer offset %d is not allowed\n", 6950 - reg_type_str[type], reg->off); 6887 + reg_type_str(env, type), reg->off); 6951 6888 return false; 6952 6889 } 6953 6890 6954 6891 if (smin == S64_MIN) { 6955 6892 verbose(env, "math between %s pointer and register with unbounded min value is not allowed\n", 6956 - reg_type_str[type]); 6893 + reg_type_str(env, type)); 6957 6894 return false; 6958 6895 } 6959 6896 6960 6897 if (smin >= BPF_MAX_VAR_OFF || smin <= -BPF_MAX_VAR_OFF) { 6961 6898 verbose(env, "value %lld makes %s pointer be out of bounds\n", 6962 - smin, reg_type_str[type]); 6899 + smin, reg_type_str(env, type)); 6963 6900 return false; 6964 6901 } 6965 6902 ··· 7336 7273 return -EACCES; 7337 7274 } 7338 7275 7339 - switch (ptr_reg->type) { 7340 - case PTR_TO_MAP_VALUE_OR_NULL: 7276 + if (ptr_reg->type & PTR_MAYBE_NULL) { 7341 7277 verbose(env, "R%d pointer arithmetic on %s prohibited, null-check it first\n", 7342 - dst, reg_type_str[ptr_reg->type]); 7278 + dst, reg_type_str(env, ptr_reg->type)); 7343 7279 return -EACCES; 7280 + } 7281 + 7282 + switch (base_type(ptr_reg->type)) { 7344 7283 case CONST_PTR_TO_MAP: 7345 7284 /* smin_val represents the known value */ 7346 7285 if (known && smin_val == 0 && opcode == BPF_ADD) ··· 7350 7285 fallthrough; 7351 7286 case PTR_TO_PACKET_END: 7352 7287 case PTR_TO_SOCKET: 7353 - case PTR_TO_SOCKET_OR_NULL: 7354 7288 case PTR_TO_SOCK_COMMON: 7355 - case PTR_TO_SOCK_COMMON_OR_NULL: 7356 7289 case PTR_TO_TCP_SOCK: 7357 - case PTR_TO_TCP_SOCK_OR_NULL: 7358 7290 case PTR_TO_XDP_SOCK: 7359 7291 verbose(env, "R%d pointer arithmetic on %s prohibited\n", 7360 - dst, reg_type_str[ptr_reg->type]); 7292 + dst, reg_type_str(env, ptr_reg->type)); 7361 7293 return -EACCES; 7362 7294 default: 7363 7295 break; ··· 8327 8265 8328 8266 /* Got here implies adding two SCALAR_VALUEs */ 8329 8267 if (WARN_ON_ONCE(ptr_reg)) { 8330 - print_verifier_state(env, state); 8268 + print_verifier_state(env, state, true); 8331 8269 verbose(env, "verifier internal error: unexpected ptr_reg\n"); 8332 8270 return -EINVAL; 8333 8271 } 8334 8272 if (WARN_ON(!src_reg)) { 8335 - print_verifier_state(env, state); 8273 + print_verifier_state(env, state, true); 8336 8274 verbose(env, "verifier internal error: no src_reg\n"); 8337 8275 return -EINVAL; 8338 8276 } ··· 9077 9015 struct bpf_reg_state *reg, u32 id, 9078 9016 bool is_null) 9079 9017 { 9080 - if (reg_type_may_be_null(reg->type) && reg->id == id && 9018 + if (type_may_be_null(reg->type) && reg->id == id && 9081 9019 !WARN_ON_ONCE(!reg->id)) { 9082 9020 /* Old offset (both fixed and variable parts) should 9083 9021 * have been known-zero, because we don't allow pointer ··· 9455 9393 */ 9456 9394 if (!is_jmp32 && BPF_SRC(insn->code) == BPF_K && 9457 9395 insn->imm == 0 && (opcode == BPF_JEQ || opcode == BPF_JNE) && 9458 - reg_type_may_be_null(dst_reg->type)) { 9396 + type_may_be_null(dst_reg->type)) { 9459 9397 /* Mark all identical registers in each branch as either 9460 9398 * safe or unknown depending R == 0 or R != 0 conditional. 9461 9399 */ ··· 9471 9409 return -EACCES; 9472 9410 } 9473 9411 if (env->log.level & BPF_LOG_LEVEL) 9474 - print_verifier_state(env, this_branch->frame[this_branch->curframe]); 9412 + print_insn_state(env, this_branch->frame[this_branch->curframe]); 9475 9413 return 0; 9476 9414 } 9477 9415 ··· 9510 9448 mark_reg_known_zero(env, regs, insn->dst_reg); 9511 9449 9512 9450 dst_reg->type = aux->btf_var.reg_type; 9513 - switch (dst_reg->type) { 9451 + switch (base_type(dst_reg->type)) { 9514 9452 case PTR_TO_MEM: 9515 9453 dst_reg->mem_size = aux->btf_var.mem_size; 9516 9454 break; ··· 9709 9647 /* enforce return zero from async callbacks like timer */ 9710 9648 if (reg->type != SCALAR_VALUE) { 9711 9649 verbose(env, "In async callback the register R0 is not a known value (%s)\n", 9712 - reg_type_str[reg->type]); 9650 + reg_type_str(env, reg->type)); 9713 9651 return -EINVAL; 9714 9652 } 9715 9653 ··· 9723 9661 if (is_subprog) { 9724 9662 if (reg->type != SCALAR_VALUE) { 9725 9663 verbose(env, "At subprogram exit the register R0 is not a scalar value (%s)\n", 9726 - reg_type_str[reg->type]); 9664 + reg_type_str(env, reg->type)); 9727 9665 return -EINVAL; 9728 9666 } 9729 9667 return 0; ··· 9787 9725 9788 9726 if (reg->type != SCALAR_VALUE) { 9789 9727 verbose(env, "At program exit the register R0 is not a known value (%s)\n", 9790 - reg_type_str[reg->type]); 9728 + reg_type_str(env, reg->type)); 9791 9729 return -EINVAL; 9792 9730 } 9793 9731 ··· 10644 10582 return true; 10645 10583 if (rcur->type == NOT_INIT) 10646 10584 return false; 10647 - switch (rold->type) { 10585 + switch (base_type(rold->type)) { 10648 10586 case SCALAR_VALUE: 10649 10587 if (env->explore_alu_limits) 10650 10588 return false; ··· 10666 10604 } 10667 10605 case PTR_TO_MAP_KEY: 10668 10606 case PTR_TO_MAP_VALUE: 10607 + /* a PTR_TO_MAP_VALUE could be safe to use as a 10608 + * PTR_TO_MAP_VALUE_OR_NULL into the same map. 10609 + * However, if the old PTR_TO_MAP_VALUE_OR_NULL then got NULL- 10610 + * checked, doing so could have affected others with the same 10611 + * id, and we can't check for that because we lost the id when 10612 + * we converted to a PTR_TO_MAP_VALUE. 10613 + */ 10614 + if (type_may_be_null(rold->type)) { 10615 + if (!type_may_be_null(rcur->type)) 10616 + return false; 10617 + if (memcmp(rold, rcur, offsetof(struct bpf_reg_state, id))) 10618 + return false; 10619 + /* Check our ids match any regs they're supposed to */ 10620 + return check_ids(rold->id, rcur->id, idmap); 10621 + } 10622 + 10669 10623 /* If the new min/max/var_off satisfy the old ones and 10670 10624 * everything else matches, we are OK. 10671 10625 * 'id' is not compared, since it's only used for maps with ··· 10693 10615 return memcmp(rold, rcur, offsetof(struct bpf_reg_state, id)) == 0 && 10694 10616 range_within(rold, rcur) && 10695 10617 tnum_in(rold->var_off, rcur->var_off); 10696 - case PTR_TO_MAP_VALUE_OR_NULL: 10697 - /* a PTR_TO_MAP_VALUE could be safe to use as a 10698 - * PTR_TO_MAP_VALUE_OR_NULL into the same map. 10699 - * However, if the old PTR_TO_MAP_VALUE_OR_NULL then got NULL- 10700 - * checked, doing so could have affected others with the same 10701 - * id, and we can't check for that because we lost the id when 10702 - * we converted to a PTR_TO_MAP_VALUE. 10703 - */ 10704 - if (rcur->type != PTR_TO_MAP_VALUE_OR_NULL) 10705 - return false; 10706 - if (memcmp(rold, rcur, offsetof(struct bpf_reg_state, id))) 10707 - return false; 10708 - /* Check our ids match any regs they're supposed to */ 10709 - return check_ids(rold->id, rcur->id, idmap); 10710 10618 case PTR_TO_PACKET_META: 10711 10619 case PTR_TO_PACKET: 10712 10620 if (rcur->type != rold->type) ··· 10721 10657 case PTR_TO_PACKET_END: 10722 10658 case PTR_TO_FLOW_KEYS: 10723 10659 case PTR_TO_SOCKET: 10724 - case PTR_TO_SOCKET_OR_NULL: 10725 10660 case PTR_TO_SOCK_COMMON: 10726 - case PTR_TO_SOCK_COMMON_OR_NULL: 10727 10661 case PTR_TO_TCP_SOCK: 10728 - case PTR_TO_TCP_SOCK_OR_NULL: 10729 10662 case PTR_TO_XDP_SOCK: 10730 10663 /* Only valid matches are exact, which memcmp() above 10731 10664 * would have accepted ··· 11248 11187 /* Return true if it's OK to have the same insn return a different type. */ 11249 11188 static bool reg_type_mismatch_ok(enum bpf_reg_type type) 11250 11189 { 11251 - switch (type) { 11190 + switch (base_type(type)) { 11252 11191 case PTR_TO_CTX: 11253 11192 case PTR_TO_SOCKET: 11254 - case PTR_TO_SOCKET_OR_NULL: 11255 11193 case PTR_TO_SOCK_COMMON: 11256 - case PTR_TO_SOCK_COMMON_OR_NULL: 11257 11194 case PTR_TO_TCP_SOCK: 11258 - case PTR_TO_TCP_SOCK_OR_NULL: 11259 11195 case PTR_TO_XDP_SOCK: 11260 11196 case PTR_TO_BTF_ID: 11261 - case PTR_TO_BTF_ID_OR_NULL: 11262 11197 return false; 11263 11198 default: 11264 11199 return true; ··· 11334 11277 if (need_resched()) 11335 11278 cond_resched(); 11336 11279 11337 - if (env->log.level & BPF_LOG_LEVEL2 || 11338 - (env->log.level & BPF_LOG_LEVEL && do_print_state)) { 11339 - if (env->log.level & BPF_LOG_LEVEL2) 11340 - verbose(env, "%d:", env->insn_idx); 11341 - else 11342 - verbose(env, "\nfrom %d to %d%s:", 11343 - env->prev_insn_idx, env->insn_idx, 11344 - env->cur_state->speculative ? 11345 - " (speculative execution)" : ""); 11346 - print_verifier_state(env, state->frame[state->curframe]); 11280 + if (env->log.level & BPF_LOG_LEVEL2 && do_print_state) { 11281 + verbose(env, "\nfrom %d to %d%s:", 11282 + env->prev_insn_idx, env->insn_idx, 11283 + env->cur_state->speculative ? 11284 + " (speculative execution)" : ""); 11285 + print_verifier_state(env, state->frame[state->curframe], true); 11347 11286 do_print_state = false; 11348 11287 } 11349 11288 ··· 11350 11297 .private_data = env, 11351 11298 }; 11352 11299 11300 + if (verifier_state_scratched(env)) 11301 + print_insn_state(env, state->frame[state->curframe]); 11302 + 11353 11303 verbose_linfo(env, env->insn_idx, "; "); 11304 + env->prev_log_len = env->log.len_used; 11354 11305 verbose(env, "%d: ", env->insn_idx); 11355 11306 print_bpf_insn(&cbs, insn, env->allow_ptr_leaks); 11307 + env->prev_insn_print_len = env->log.len_used - env->prev_log_len; 11308 + env->prev_log_len = env->log.len_used; 11356 11309 } 11357 11310 11358 11311 if (bpf_prog_is_dev_bound(env->prog->aux)) { ··· 11480 11421 if (is_ctx_reg(env, insn->dst_reg)) { 11481 11422 verbose(env, "BPF_ST stores into R%d %s is not allowed\n", 11482 11423 insn->dst_reg, 11483 - reg_type_str[reg_state(env, insn->dst_reg)->type]); 11424 + reg_type_str(env, reg_state(env, insn->dst_reg)->type)); 11484 11425 return -EACCES; 11485 11426 } 11486 11427 ··· 11567 11508 if (err) 11568 11509 return err; 11569 11510 process_bpf_exit: 11511 + mark_verifier_state_scratched(env); 11570 11512 update_branch_counts(env, env->cur_state); 11571 11513 err = pop_stack(env, &prev_insn_idx, 11572 11514 &env->insn_idx, pop_log); ··· 11733 11673 err = -EINVAL; 11734 11674 goto err_put; 11735 11675 } 11736 - aux->btf_var.reg_type = PTR_TO_MEM; 11676 + aux->btf_var.reg_type = PTR_TO_MEM | MEM_RDONLY; 11737 11677 aux->btf_var.mem_size = tsize; 11738 11678 } else { 11739 11679 aux->btf_var.reg_type = PTR_TO_BTF_ID; ··· 11893 11833 } 11894 11834 break; 11895 11835 case BPF_MAP_TYPE_RINGBUF: 11836 + case BPF_MAP_TYPE_INODE_STORAGE: 11837 + case BPF_MAP_TYPE_SK_STORAGE: 11838 + case BPF_MAP_TYPE_TASK_STORAGE: 11896 11839 break; 11897 11840 default: 11898 11841 verbose(env, ··· 13079 13016 static int do_misc_fixups(struct bpf_verifier_env *env) 13080 13017 { 13081 13018 struct bpf_prog *prog = env->prog; 13019 + enum bpf_attach_type eatype = prog->expected_attach_type; 13082 13020 bool expect_blinding = bpf_jit_blinding_enabled(prog); 13083 13021 enum bpf_prog_type prog_type = resolve_prog_type(prog); 13084 13022 struct bpf_insn *insn = prog->insnsi; ··· 13450 13386 continue; 13451 13387 } 13452 13388 13389 + /* Implement bpf_get_func_arg inline. */ 13390 + if (prog_type == BPF_PROG_TYPE_TRACING && 13391 + insn->imm == BPF_FUNC_get_func_arg) { 13392 + /* Load nr_args from ctx - 8 */ 13393 + insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8); 13394 + insn_buf[1] = BPF_JMP32_REG(BPF_JGE, BPF_REG_2, BPF_REG_0, 6); 13395 + insn_buf[2] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 3); 13396 + insn_buf[3] = BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1); 13397 + insn_buf[4] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0); 13398 + insn_buf[5] = BPF_STX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0); 13399 + insn_buf[6] = BPF_MOV64_IMM(BPF_REG_0, 0); 13400 + insn_buf[7] = BPF_JMP_A(1); 13401 + insn_buf[8] = BPF_MOV64_IMM(BPF_REG_0, -EINVAL); 13402 + cnt = 9; 13403 + 13404 + new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt); 13405 + if (!new_prog) 13406 + return -ENOMEM; 13407 + 13408 + delta += cnt - 1; 13409 + env->prog = prog = new_prog; 13410 + insn = new_prog->insnsi + i + delta; 13411 + continue; 13412 + } 13413 + 13414 + /* Implement bpf_get_func_ret inline. */ 13415 + if (prog_type == BPF_PROG_TYPE_TRACING && 13416 + insn->imm == BPF_FUNC_get_func_ret) { 13417 + if (eatype == BPF_TRACE_FEXIT || 13418 + eatype == BPF_MODIFY_RETURN) { 13419 + /* Load nr_args from ctx - 8 */ 13420 + insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8); 13421 + insn_buf[1] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_0, 3); 13422 + insn_buf[2] = BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1); 13423 + insn_buf[3] = BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0); 13424 + insn_buf[4] = BPF_STX_MEM(BPF_DW, BPF_REG_2, BPF_REG_3, 0); 13425 + insn_buf[5] = BPF_MOV64_IMM(BPF_REG_0, 0); 13426 + cnt = 6; 13427 + } else { 13428 + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, -EOPNOTSUPP); 13429 + cnt = 1; 13430 + } 13431 + 13432 + new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt); 13433 + if (!new_prog) 13434 + return -ENOMEM; 13435 + 13436 + delta += cnt - 1; 13437 + env->prog = prog = new_prog; 13438 + insn = new_prog->insnsi + i + delta; 13439 + continue; 13440 + } 13441 + 13442 + /* Implement get_func_arg_cnt inline. */ 13443 + if (prog_type == BPF_PROG_TYPE_TRACING && 13444 + insn->imm == BPF_FUNC_get_func_arg_cnt) { 13445 + /* Load nr_args from ctx - 8 */ 13446 + insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8); 13447 + 13448 + new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, 1); 13449 + if (!new_prog) 13450 + return -ENOMEM; 13451 + 13452 + env->prog = prog = new_prog; 13453 + insn = new_prog->insnsi + i + delta; 13454 + continue; 13455 + } 13456 + 13453 13457 /* Implement bpf_get_func_ip inline. */ 13454 13458 if (prog_type == BPF_PROG_TYPE_TRACING && 13455 13459 insn->imm == BPF_FUNC_get_func_ip) { 13456 - /* Load IP address from ctx - 8 */ 13457 - insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8); 13460 + /* Load IP address from ctx - 16 */ 13461 + insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -16); 13458 13462 13459 13463 new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, 1); 13460 13464 if (!new_prog) ··· 13636 13504 mark_reg_known_zero(env, regs, i); 13637 13505 else if (regs[i].type == SCALAR_VALUE) 13638 13506 mark_reg_unknown(env, regs, i); 13639 - else if (regs[i].type == PTR_TO_MEM_OR_NULL) { 13507 + else if (base_type(regs[i].type) == PTR_TO_MEM) { 13640 13508 const u32 mem_size = regs[i].mem_size; 13641 13509 13642 13510 mark_reg_known_zero(env, regs, i); ··· 14230 14098 goto err_unlock; 14231 14099 } 14232 14100 } 14101 + 14102 + mark_verifier_state_clean(env); 14233 14103 14234 14104 if (IS_ERR(btf_vmlinux)) { 14235 14105 /* Either gcc or pahole or kernel are broken. */
+1
kernel/cgroup/cgroup.c
··· 30 30 31 31 #include "cgroup-internal.h" 32 32 33 + #include <linux/bpf-cgroup.h> 33 34 #include <linux/cred.h> 34 35 #include <linux/errno.h> 35 36 #include <linux/init_task.h>
+1
kernel/sysctl.c
··· 33 33 #include <linux/security.h> 34 34 #include <linux/ctype.h> 35 35 #include <linux/kmemleak.h> 36 + #include <linux/filter.h> 36 37 #include <linux/fs.h> 37 38 #include <linux/init.h> 38 39 #include <linux/kernel.h>
+67 -14
kernel/trace/bpf_trace.c
··· 345 345 .gpl_only = true, 346 346 .ret_type = RET_INTEGER, 347 347 .arg1_type = ARG_ANYTHING, 348 - .arg2_type = ARG_PTR_TO_MEM, 348 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 349 349 .arg3_type = ARG_CONST_SIZE, 350 350 }; 351 351 ··· 394 394 .func = bpf_trace_printk, 395 395 .gpl_only = true, 396 396 .ret_type = RET_INTEGER, 397 - .arg1_type = ARG_PTR_TO_MEM, 397 + .arg1_type = ARG_PTR_TO_MEM | MEM_RDONLY, 398 398 .arg2_type = ARG_CONST_SIZE, 399 399 }; 400 400 ··· 450 450 .func = bpf_trace_vprintk, 451 451 .gpl_only = true, 452 452 .ret_type = RET_INTEGER, 453 - .arg1_type = ARG_PTR_TO_MEM, 453 + .arg1_type = ARG_PTR_TO_MEM | MEM_RDONLY, 454 454 .arg2_type = ARG_CONST_SIZE, 455 - .arg3_type = ARG_PTR_TO_MEM_OR_NULL, 455 + .arg3_type = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY, 456 456 .arg4_type = ARG_CONST_SIZE_OR_ZERO, 457 457 }; 458 458 ··· 492 492 .ret_type = RET_INTEGER, 493 493 .arg1_type = ARG_PTR_TO_BTF_ID, 494 494 .arg1_btf_id = &btf_seq_file_ids[0], 495 - .arg2_type = ARG_PTR_TO_MEM, 495 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 496 496 .arg3_type = ARG_CONST_SIZE, 497 - .arg4_type = ARG_PTR_TO_MEM_OR_NULL, 497 + .arg4_type = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY, 498 498 .arg5_type = ARG_CONST_SIZE_OR_ZERO, 499 499 }; 500 500 ··· 509 509 .ret_type = RET_INTEGER, 510 510 .arg1_type = ARG_PTR_TO_BTF_ID, 511 511 .arg1_btf_id = &btf_seq_file_ids[0], 512 - .arg2_type = ARG_PTR_TO_MEM, 512 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 513 513 .arg3_type = ARG_CONST_SIZE_OR_ZERO, 514 514 }; 515 515 ··· 533 533 .ret_type = RET_INTEGER, 534 534 .arg1_type = ARG_PTR_TO_BTF_ID, 535 535 .arg1_btf_id = &btf_seq_file_ids[0], 536 - .arg2_type = ARG_PTR_TO_MEM, 536 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 537 537 .arg3_type = ARG_CONST_SIZE_OR_ZERO, 538 538 .arg4_type = ARG_ANYTHING, 539 539 }; ··· 694 694 .arg1_type = ARG_PTR_TO_CTX, 695 695 .arg2_type = ARG_CONST_MAP_PTR, 696 696 .arg3_type = ARG_ANYTHING, 697 - .arg4_type = ARG_PTR_TO_MEM, 697 + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 698 698 .arg5_type = ARG_CONST_SIZE_OR_ZERO, 699 699 }; 700 700 ··· 1004 1004 .ret_type = RET_INTEGER, 1005 1005 .arg1_type = ARG_PTR_TO_MEM, 1006 1006 .arg2_type = ARG_CONST_SIZE, 1007 - .arg3_type = ARG_PTR_TO_MEM, 1007 + .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, 1008 1008 .arg4_type = ARG_CONST_SIZE, 1009 1009 .arg5_type = ARG_ANYTHING, 1010 1010 }; ··· 1012 1012 BPF_CALL_1(bpf_get_func_ip_tracing, void *, ctx) 1013 1013 { 1014 1014 /* This helper call is inlined by verifier. */ 1015 - return ((u64 *)ctx)[-1]; 1015 + return ((u64 *)ctx)[-2]; 1016 1016 } 1017 1017 1018 1018 static const struct bpf_func_proto bpf_get_func_ip_proto_tracing = { ··· 1089 1089 .ret_type = RET_INTEGER, 1090 1090 .arg1_type = ARG_PTR_TO_UNINIT_MEM, 1091 1091 .arg2_type = ARG_CONST_SIZE_OR_ZERO, 1092 + }; 1093 + 1094 + BPF_CALL_3(get_func_arg, void *, ctx, u32, n, u64 *, value) 1095 + { 1096 + /* This helper call is inlined by verifier. */ 1097 + u64 nr_args = ((u64 *)ctx)[-1]; 1098 + 1099 + if ((u64) n >= nr_args) 1100 + return -EINVAL; 1101 + *value = ((u64 *)ctx)[n]; 1102 + return 0; 1103 + } 1104 + 1105 + static const struct bpf_func_proto bpf_get_func_arg_proto = { 1106 + .func = get_func_arg, 1107 + .ret_type = RET_INTEGER, 1108 + .arg1_type = ARG_PTR_TO_CTX, 1109 + .arg2_type = ARG_ANYTHING, 1110 + .arg3_type = ARG_PTR_TO_LONG, 1111 + }; 1112 + 1113 + BPF_CALL_2(get_func_ret, void *, ctx, u64 *, value) 1114 + { 1115 + /* This helper call is inlined by verifier. */ 1116 + u64 nr_args = ((u64 *)ctx)[-1]; 1117 + 1118 + *value = ((u64 *)ctx)[nr_args]; 1119 + return 0; 1120 + } 1121 + 1122 + static const struct bpf_func_proto bpf_get_func_ret_proto = { 1123 + .func = get_func_ret, 1124 + .ret_type = RET_INTEGER, 1125 + .arg1_type = ARG_PTR_TO_CTX, 1126 + .arg2_type = ARG_PTR_TO_LONG, 1127 + }; 1128 + 1129 + BPF_CALL_1(get_func_arg_cnt, void *, ctx) 1130 + { 1131 + /* This helper call is inlined by verifier. */ 1132 + return ((u64 *)ctx)[-1]; 1133 + } 1134 + 1135 + static const struct bpf_func_proto bpf_get_func_arg_cnt_proto = { 1136 + .func = get_func_arg_cnt, 1137 + .ret_type = RET_INTEGER, 1138 + .arg1_type = ARG_PTR_TO_CTX, 1092 1139 }; 1093 1140 1094 1141 static const struct bpf_func_proto * ··· 1334 1287 .arg1_type = ARG_PTR_TO_CTX, 1335 1288 .arg2_type = ARG_CONST_MAP_PTR, 1336 1289 .arg3_type = ARG_ANYTHING, 1337 - .arg4_type = ARG_PTR_TO_MEM, 1290 + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 1338 1291 .arg5_type = ARG_CONST_SIZE_OR_ZERO, 1339 1292 }; 1340 1293 ··· 1556 1509 .arg1_type = ARG_PTR_TO_CTX, 1557 1510 .arg2_type = ARG_CONST_MAP_PTR, 1558 1511 .arg3_type = ARG_ANYTHING, 1559 - .arg4_type = ARG_PTR_TO_MEM, 1512 + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 1560 1513 .arg5_type = ARG_CONST_SIZE_OR_ZERO, 1561 1514 }; 1562 1515 ··· 1610 1563 .gpl_only = true, 1611 1564 .ret_type = RET_INTEGER, 1612 1565 .arg1_type = ARG_PTR_TO_CTX, 1613 - .arg2_type = ARG_PTR_TO_MEM, 1566 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 1614 1567 .arg3_type = ARG_CONST_SIZE_OR_ZERO, 1615 1568 .arg4_type = ARG_ANYTHING, 1616 1569 }; ··· 1676 1629 NULL; 1677 1630 case BPF_FUNC_d_path: 1678 1631 return &bpf_d_path_proto; 1632 + case BPF_FUNC_get_func_arg: 1633 + return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_proto : NULL; 1634 + case BPF_FUNC_get_func_ret: 1635 + return bpf_prog_has_trampoline(prog) ? &bpf_get_func_ret_proto : NULL; 1636 + case BPF_FUNC_get_func_arg_cnt: 1637 + return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL; 1679 1638 default: 1680 1639 fn = raw_tp_prog_func_proto(func_id, prog); 1681 1640 if (!fn && prog->expected_attach_type == BPF_TRACE_ITER)
+1
kernel/trace/trace_kprobe.c
··· 7 7 */ 8 8 #define pr_fmt(fmt) "trace_kprobe: " fmt 9 9 10 + #include <linux/bpf-cgroup.h> 10 11 #include <linux/security.h> 11 12 #include <linux/module.h> 12 13 #include <linux/uaccess.h>
+1
kernel/trace/trace_uprobe.c
··· 7 7 */ 8 8 #define pr_fmt(fmt) "trace_uprobe: " fmt 9 9 10 + #include <linux/bpf-cgroup.h> 10 11 #include <linux/security.h> 11 12 #include <linux/ctype.h> 12 13 #include <linux/module.h>
+1
net/bluetooth/bnep/sock.c
··· 24 24 SOFTWARE IS DISCLAIMED. 25 25 */ 26 26 27 + #include <linux/compat.h> 27 28 #include <linux/export.h> 28 29 #include <linux/file.h> 29 30
+2
net/bluetooth/eir.h
··· 5 5 * Copyright (C) 2021 Intel Corporation 6 6 */ 7 7 8 + #include <asm/unaligned.h> 9 + 8 10 void eir_create(struct hci_dev *hdev, u8 *data); 9 11 10 12 u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr);
+1
net/bluetooth/hidp/sock.c
··· 20 20 SOFTWARE IS DISCLAIMED. 21 21 */ 22 22 23 + #include <linux/compat.h> 23 24 #include <linux/export.h> 24 25 #include <linux/file.h> 25 26
+1
net/bluetooth/l2cap_sock.c
··· 29 29 30 30 #include <linux/module.h> 31 31 #include <linux/export.h> 32 + #include <linux/filter.h> 32 33 #include <linux/sched/signal.h> 33 34 34 35 #include <net/bluetooth/bluetooth.h>
+1
net/bridge/br_ioctl.c
··· 8 8 */ 9 9 10 10 #include <linux/capability.h> 11 + #include <linux/compat.h> 11 12 #include <linux/kernel.h> 12 13 #include <linux/if_bridge.h> 13 14 #include <linux/netdevice.h>
+1
net/caif/caif_socket.c
··· 6 6 7 7 #define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ 8 8 9 + #include <linux/filter.h> 9 10 #include <linux/fs.h> 10 11 #include <linux/init.h> 11 12 #include <linux/module.h>
+8 -2
net/core/bpf_sk_storage.c
··· 13 13 #include <net/sock.h> 14 14 #include <uapi/linux/sock_diag.h> 15 15 #include <uapi/linux/btf.h> 16 + #include <linux/rcupdate_trace.h> 16 17 17 18 DEFINE_BPF_STORAGE_CACHE(sk_cache); 18 19 ··· 23 22 struct bpf_local_storage *sk_storage; 24 23 struct bpf_local_storage_map *smap; 25 24 26 - sk_storage = rcu_dereference(sk->sk_bpf_storage); 25 + sk_storage = 26 + rcu_dereference_check(sk->sk_bpf_storage, bpf_rcu_lock_held()); 27 27 if (!sk_storage) 28 28 return NULL; 29 29 ··· 260 258 { 261 259 struct bpf_local_storage_data *sdata; 262 260 261 + WARN_ON_ONCE(!bpf_rcu_lock_held()); 263 262 if (!sk || !sk_fullsock(sk) || flags > BPF_SK_STORAGE_GET_F_CREATE) 264 263 return (unsigned long)NULL; 265 264 ··· 291 288 292 289 BPF_CALL_2(bpf_sk_storage_delete, struct bpf_map *, map, struct sock *, sk) 293 290 { 291 + WARN_ON_ONCE(!bpf_rcu_lock_held()); 294 292 if (!sk || !sk_fullsock(sk)) 295 293 return -EINVAL; 296 294 ··· 420 416 BPF_CALL_4(bpf_sk_storage_get_tracing, struct bpf_map *, map, struct sock *, sk, 421 417 void *, value, u64, flags) 422 418 { 419 + WARN_ON_ONCE(!bpf_rcu_lock_held()); 423 420 if (in_hardirq() || in_nmi()) 424 421 return (unsigned long)NULL; 425 422 ··· 430 425 BPF_CALL_2(bpf_sk_storage_delete_tracing, struct bpf_map *, map, 431 426 struct sock *, sk) 432 427 { 428 + WARN_ON_ONCE(!bpf_rcu_lock_held()); 433 429 if (in_hardirq() || in_nmi()) 434 430 return -EPERM; 435 431 ··· 935 929 { offsetof(struct bpf_iter__bpf_sk_storage_map, sk), 936 930 PTR_TO_BTF_ID_OR_NULL }, 937 931 { offsetof(struct bpf_iter__bpf_sk_storage_map, value), 938 - PTR_TO_RDWR_BUF_OR_NULL }, 932 + PTR_TO_BUF | PTR_MAYBE_NULL }, 939 933 }, 940 934 .seq_info = &iter_seq_info, 941 935 };
+1 -1
net/core/dev.c
··· 4712 4712 case XDP_PASS: 4713 4713 break; 4714 4714 default: 4715 - bpf_warn_invalid_xdp_action(act); 4715 + bpf_warn_invalid_xdp_action(skb->dev, xdp_prog, act); 4716 4716 fallthrough; 4717 4717 case XDP_ABORTED: 4718 4718 trace_xdp_exception(skb->dev, xdp_prog, act);
+1
net/core/devlink.c
··· 7 7 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> 8 8 */ 9 9 10 + #include <linux/etherdevice.h> 10 11 #include <linux/kernel.h> 11 12 #include <linux/module.h> 12 13 #include <linux/types.h>
+36 -36
net/core/filter.c
··· 1712 1712 .ret_type = RET_INTEGER, 1713 1713 .arg1_type = ARG_PTR_TO_CTX, 1714 1714 .arg2_type = ARG_ANYTHING, 1715 - .arg3_type = ARG_PTR_TO_MEM, 1715 + .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, 1716 1716 .arg4_type = ARG_CONST_SIZE, 1717 1717 .arg5_type = ARG_ANYTHING, 1718 1718 }; ··· 2017 2017 .gpl_only = false, 2018 2018 .pkt_access = true, 2019 2019 .ret_type = RET_INTEGER, 2020 - .arg1_type = ARG_PTR_TO_MEM_OR_NULL, 2020 + .arg1_type = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY, 2021 2021 .arg2_type = ARG_CONST_SIZE_OR_ZERO, 2022 - .arg3_type = ARG_PTR_TO_MEM_OR_NULL, 2022 + .arg3_type = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY, 2023 2023 .arg4_type = ARG_CONST_SIZE_OR_ZERO, 2024 2024 .arg5_type = ARG_ANYTHING, 2025 2025 }; ··· 2540 2540 .gpl_only = false, 2541 2541 .ret_type = RET_INTEGER, 2542 2542 .arg1_type = ARG_ANYTHING, 2543 - .arg2_type = ARG_PTR_TO_MEM_OR_NULL, 2543 + .arg2_type = ARG_PTR_TO_MEM | PTR_MAYBE_NULL | MEM_RDONLY, 2544 2544 .arg3_type = ARG_CONST_SIZE_OR_ZERO, 2545 2545 .arg4_type = ARG_ANYTHING, 2546 2546 }; ··· 4173 4173 .arg1_type = ARG_PTR_TO_CTX, 4174 4174 .arg2_type = ARG_CONST_MAP_PTR, 4175 4175 .arg3_type = ARG_ANYTHING, 4176 - .arg4_type = ARG_PTR_TO_MEM, 4176 + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 4177 4177 .arg5_type = ARG_CONST_SIZE_OR_ZERO, 4178 4178 }; 4179 4179 ··· 4187 4187 .arg1_btf_id = &bpf_skb_output_btf_ids[0], 4188 4188 .arg2_type = ARG_CONST_MAP_PTR, 4189 4189 .arg3_type = ARG_ANYTHING, 4190 - .arg4_type = ARG_PTR_TO_MEM, 4190 + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 4191 4191 .arg5_type = ARG_CONST_SIZE_OR_ZERO, 4192 4192 }; 4193 4193 ··· 4370 4370 .gpl_only = false, 4371 4371 .ret_type = RET_INTEGER, 4372 4372 .arg1_type = ARG_PTR_TO_CTX, 4373 - .arg2_type = ARG_PTR_TO_MEM, 4373 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 4374 4374 .arg3_type = ARG_CONST_SIZE, 4375 4375 .arg4_type = ARG_ANYTHING, 4376 4376 }; ··· 4396 4396 .gpl_only = false, 4397 4397 .ret_type = RET_INTEGER, 4398 4398 .arg1_type = ARG_PTR_TO_CTX, 4399 - .arg2_type = ARG_PTR_TO_MEM, 4399 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 4400 4400 .arg3_type = ARG_CONST_SIZE, 4401 4401 }; 4402 4402 ··· 4566 4566 .arg1_type = ARG_PTR_TO_CTX, 4567 4567 .arg2_type = ARG_CONST_MAP_PTR, 4568 4568 .arg3_type = ARG_ANYTHING, 4569 - .arg4_type = ARG_PTR_TO_MEM, 4569 + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 4570 4570 .arg5_type = ARG_CONST_SIZE_OR_ZERO, 4571 4571 }; 4572 4572 ··· 4580 4580 .arg1_btf_id = &bpf_xdp_output_btf_ids[0], 4581 4581 .arg2_type = ARG_CONST_MAP_PTR, 4582 4582 .arg3_type = ARG_ANYTHING, 4583 - .arg4_type = ARG_PTR_TO_MEM, 4583 + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 4584 4584 .arg5_type = ARG_CONST_SIZE_OR_ZERO, 4585 4585 }; 4586 4586 ··· 5066 5066 .arg1_type = ARG_PTR_TO_BTF_ID_SOCK_COMMON, 5067 5067 .arg2_type = ARG_ANYTHING, 5068 5068 .arg3_type = ARG_ANYTHING, 5069 - .arg4_type = ARG_PTR_TO_MEM, 5069 + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 5070 5070 .arg5_type = ARG_CONST_SIZE, 5071 5071 }; 5072 5072 ··· 5100 5100 .arg1_type = ARG_PTR_TO_CTX, 5101 5101 .arg2_type = ARG_ANYTHING, 5102 5102 .arg3_type = ARG_ANYTHING, 5103 - .arg4_type = ARG_PTR_TO_MEM, 5103 + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 5104 5104 .arg5_type = ARG_CONST_SIZE, 5105 5105 }; 5106 5106 ··· 5134 5134 .arg1_type = ARG_PTR_TO_CTX, 5135 5135 .arg2_type = ARG_ANYTHING, 5136 5136 .arg3_type = ARG_ANYTHING, 5137 - .arg4_type = ARG_PTR_TO_MEM, 5137 + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 5138 5138 .arg5_type = ARG_CONST_SIZE, 5139 5139 }; 5140 5140 ··· 5309 5309 .gpl_only = false, 5310 5310 .ret_type = RET_INTEGER, 5311 5311 .arg1_type = ARG_PTR_TO_CTX, 5312 - .arg2_type = ARG_PTR_TO_MEM, 5312 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 5313 5313 .arg3_type = ARG_CONST_SIZE, 5314 5314 }; 5315 5315 ··· 5897 5897 .ret_type = RET_INTEGER, 5898 5898 .arg1_type = ARG_PTR_TO_CTX, 5899 5899 .arg2_type = ARG_ANYTHING, 5900 - .arg3_type = ARG_PTR_TO_MEM, 5900 + .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, 5901 5901 .arg4_type = ARG_CONST_SIZE 5902 5902 }; 5903 5903 ··· 5907 5907 .ret_type = RET_INTEGER, 5908 5908 .arg1_type = ARG_PTR_TO_CTX, 5909 5909 .arg2_type = ARG_ANYTHING, 5910 - .arg3_type = ARG_PTR_TO_MEM, 5910 + .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, 5911 5911 .arg4_type = ARG_CONST_SIZE 5912 5912 }; 5913 5913 ··· 5950 5950 .ret_type = RET_INTEGER, 5951 5951 .arg1_type = ARG_PTR_TO_CTX, 5952 5952 .arg2_type = ARG_ANYTHING, 5953 - .arg3_type = ARG_PTR_TO_MEM, 5953 + .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, 5954 5954 .arg4_type = ARG_CONST_SIZE 5955 5955 }; 5956 5956 ··· 6038 6038 .ret_type = RET_INTEGER, 6039 6039 .arg1_type = ARG_PTR_TO_CTX, 6040 6040 .arg2_type = ARG_ANYTHING, 6041 - .arg3_type = ARG_PTR_TO_MEM, 6041 + .arg3_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6042 6042 .arg4_type = ARG_CONST_SIZE 6043 6043 }; 6044 6044 ··· 6263 6263 .pkt_access = true, 6264 6264 .ret_type = RET_PTR_TO_SOCK_COMMON_OR_NULL, 6265 6265 .arg1_type = ARG_PTR_TO_CTX, 6266 - .arg2_type = ARG_PTR_TO_MEM, 6266 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6267 6267 .arg3_type = ARG_CONST_SIZE, 6268 6268 .arg4_type = ARG_ANYTHING, 6269 6269 .arg5_type = ARG_ANYTHING, ··· 6282 6282 .pkt_access = true, 6283 6283 .ret_type = RET_PTR_TO_SOCKET_OR_NULL, 6284 6284 .arg1_type = ARG_PTR_TO_CTX, 6285 - .arg2_type = ARG_PTR_TO_MEM, 6285 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6286 6286 .arg3_type = ARG_CONST_SIZE, 6287 6287 .arg4_type = ARG_ANYTHING, 6288 6288 .arg5_type = ARG_ANYTHING, ··· 6301 6301 .pkt_access = true, 6302 6302 .ret_type = RET_PTR_TO_SOCKET_OR_NULL, 6303 6303 .arg1_type = ARG_PTR_TO_CTX, 6304 - .arg2_type = ARG_PTR_TO_MEM, 6304 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6305 6305 .arg3_type = ARG_CONST_SIZE, 6306 6306 .arg4_type = ARG_ANYTHING, 6307 6307 .arg5_type = ARG_ANYTHING, ··· 6338 6338 .pkt_access = true, 6339 6339 .ret_type = RET_PTR_TO_SOCKET_OR_NULL, 6340 6340 .arg1_type = ARG_PTR_TO_CTX, 6341 - .arg2_type = ARG_PTR_TO_MEM, 6341 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6342 6342 .arg3_type = ARG_CONST_SIZE, 6343 6343 .arg4_type = ARG_ANYTHING, 6344 6344 .arg5_type = ARG_ANYTHING, ··· 6361 6361 .pkt_access = true, 6362 6362 .ret_type = RET_PTR_TO_SOCK_COMMON_OR_NULL, 6363 6363 .arg1_type = ARG_PTR_TO_CTX, 6364 - .arg2_type = ARG_PTR_TO_MEM, 6364 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6365 6365 .arg3_type = ARG_CONST_SIZE, 6366 6366 .arg4_type = ARG_ANYTHING, 6367 6367 .arg5_type = ARG_ANYTHING, ··· 6384 6384 .pkt_access = true, 6385 6385 .ret_type = RET_PTR_TO_SOCKET_OR_NULL, 6386 6386 .arg1_type = ARG_PTR_TO_CTX, 6387 - .arg2_type = ARG_PTR_TO_MEM, 6387 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6388 6388 .arg3_type = ARG_CONST_SIZE, 6389 6389 .arg4_type = ARG_ANYTHING, 6390 6390 .arg5_type = ARG_ANYTHING, ··· 6403 6403 .gpl_only = false, 6404 6404 .ret_type = RET_PTR_TO_SOCK_COMMON_OR_NULL, 6405 6405 .arg1_type = ARG_PTR_TO_CTX, 6406 - .arg2_type = ARG_PTR_TO_MEM, 6406 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6407 6407 .arg3_type = ARG_CONST_SIZE, 6408 6408 .arg4_type = ARG_ANYTHING, 6409 6409 .arg5_type = ARG_ANYTHING, ··· 6422 6422 .gpl_only = false, 6423 6423 .ret_type = RET_PTR_TO_SOCKET_OR_NULL, 6424 6424 .arg1_type = ARG_PTR_TO_CTX, 6425 - .arg2_type = ARG_PTR_TO_MEM, 6425 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6426 6426 .arg3_type = ARG_CONST_SIZE, 6427 6427 .arg4_type = ARG_ANYTHING, 6428 6428 .arg5_type = ARG_ANYTHING, ··· 6441 6441 .gpl_only = false, 6442 6442 .ret_type = RET_PTR_TO_SOCKET_OR_NULL, 6443 6443 .arg1_type = ARG_PTR_TO_CTX, 6444 - .arg2_type = ARG_PTR_TO_MEM, 6444 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6445 6445 .arg3_type = ARG_CONST_SIZE, 6446 6446 .arg4_type = ARG_ANYTHING, 6447 6447 .arg5_type = ARG_ANYTHING, ··· 6754 6754 .pkt_access = true, 6755 6755 .ret_type = RET_INTEGER, 6756 6756 .arg1_type = ARG_PTR_TO_BTF_ID_SOCK_COMMON, 6757 - .arg2_type = ARG_PTR_TO_MEM, 6757 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6758 6758 .arg3_type = ARG_CONST_SIZE, 6759 - .arg4_type = ARG_PTR_TO_MEM, 6759 + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6760 6760 .arg5_type = ARG_CONST_SIZE, 6761 6761 }; 6762 6762 ··· 6823 6823 .pkt_access = true, 6824 6824 .ret_type = RET_INTEGER, 6825 6825 .arg1_type = ARG_PTR_TO_BTF_ID_SOCK_COMMON, 6826 - .arg2_type = ARG_PTR_TO_MEM, 6826 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6827 6827 .arg3_type = ARG_CONST_SIZE, 6828 - .arg4_type = ARG_PTR_TO_MEM, 6828 + .arg4_type = ARG_PTR_TO_MEM | MEM_RDONLY, 6829 6829 .arg5_type = ARG_CONST_SIZE, 6830 6830 }; 6831 6831 ··· 7054 7054 .gpl_only = false, 7055 7055 .ret_type = RET_INTEGER, 7056 7056 .arg1_type = ARG_PTR_TO_CTX, 7057 - .arg2_type = ARG_PTR_TO_MEM, 7057 + .arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY, 7058 7058 .arg3_type = ARG_CONST_SIZE, 7059 7059 .arg4_type = ARG_ANYTHING, 7060 7060 }; ··· 8180 8180 return __is_valid_xdp_access(off, size); 8181 8181 } 8182 8182 8183 - void bpf_warn_invalid_xdp_action(u32 act) 8183 + void bpf_warn_invalid_xdp_action(struct net_device *dev, struct bpf_prog *prog, u32 act) 8184 8184 { 8185 8185 const u32 act_max = XDP_REDIRECT; 8186 8186 8187 - WARN_ONCE(1, "%s XDP return value %u, expect packet loss!\n", 8188 - act > act_max ? "Illegal" : "Driver unsupported", 8189 - act); 8187 + pr_warn_once("%s XDP return value %u on prog %s (id %d) dev %s, expect packet loss!\n", 8188 + act > act_max ? "Illegal" : "Driver unsupported", 8189 + act, prog->aux->name, prog->aux->id, dev ? dev->name : "N/A"); 8190 8190 } 8191 8191 EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action); 8192 8192
+1
net/core/flow_dissector.c
··· 5 5 #include <linux/ip.h> 6 6 #include <linux/ipv6.h> 7 7 #include <linux/if_vlan.h> 8 + #include <linux/filter.h> 8 9 #include <net/dsa.h> 9 10 #include <net/dst_metadata.h> 10 11 #include <net/ip.h>
+1
net/core/lwt_bpf.c
··· 2 2 /* Copyright (c) 2016 Thomas Graf <tgraf@tgraf.ch> 3 3 */ 4 4 5 + #include <linux/filter.h> 5 6 #include <linux/kernel.h> 6 7 #include <linux/module.h> 7 8 #include <linux/skbuff.h>
+1
net/core/sock_diag.c
··· 1 1 /* License: GPL */ 2 2 3 + #include <linux/filter.h> 3 4 #include <linux/mutex.h> 4 5 #include <linux/socket.h> 5 6 #include <linux/skbuff.h>
+1 -1
net/core/sock_map.c
··· 1564 1564 .ctx_arg_info_size = 2, 1565 1565 .ctx_arg_info = { 1566 1566 { offsetof(struct bpf_iter__sockmap, key), 1567 - PTR_TO_RDONLY_BUF_OR_NULL }, 1567 + PTR_TO_BUF | PTR_MAYBE_NULL | MEM_RDONLY }, 1568 1568 { offsetof(struct bpf_iter__sockmap, sk), 1569 1569 PTR_TO_BTF_ID_OR_NULL }, 1570 1570 },
+1
net/core/sysctl_net_core.c
··· 6 6 * Added /proc/sys/net/core directory entry (empty =) ). [MS] 7 7 */ 8 8 9 + #include <linux/filter.h> 9 10 #include <linux/mm.h> 10 11 #include <linux/sysctl.h> 11 12 #include <linux/module.h>
+1
net/decnet/dn_nsp_in.c
··· 38 38 *******************************************************************************/ 39 39 40 40 #include <linux/errno.h> 41 + #include <linux/filter.h> 41 42 #include <linux/types.h> 42 43 #include <linux/socket.h> 43 44 #include <linux/in.h>
+1
net/dsa/dsa_priv.h
··· 8 8 #define __DSA_PRIV_H 9 9 10 10 #include <linux/if_bridge.h> 11 + #include <linux/if_vlan.h> 11 12 #include <linux/phy.h> 12 13 #include <linux/netdevice.h> 13 14 #include <linux/netpoll.h>
+1
net/ethtool/ioctl.c
··· 8 8 */ 9 9 10 10 #include <linux/compat.h> 11 + #include <linux/etherdevice.h> 11 12 #include <linux/module.h> 12 13 #include <linux/types.h> 13 14 #include <linux/capability.h>
+1
net/ipv4/nexthop.c
··· 8 8 #include <linux/nexthop.h> 9 9 #include <linux/rtnetlink.h> 10 10 #include <linux/slab.h> 11 + #include <linux/vmalloc.h> 11 12 #include <net/arp.h> 12 13 #include <net/ipv6_stubs.h> 13 14 #include <net/lwtunnel.h>
+1
net/ipv4/udp.c
··· 74 74 75 75 #define pr_fmt(fmt) "UDP: " fmt 76 76 77 + #include <linux/bpf-cgroup.h> 77 78 #include <linux/uaccess.h> 78 79 #include <asm/ioctls.h> 79 80 #include <linux/memblock.h>
+1
net/ipv6/ip6_fib.c
··· 15 15 16 16 #define pr_fmt(fmt) "IPv6: " fmt 17 17 18 + #include <linux/bpf.h> 18 19 #include <linux/errno.h> 19 20 #include <linux/types.h> 20 21 #include <linux/net.h>
+1
net/ipv6/seg6_local.c
··· 7 7 * eBPF support: Mathieu Xhonneux <m.xhonneux@gmail.com> 8 8 */ 9 9 10 + #include <linux/filter.h> 10 11 #include <linux/types.h> 11 12 #include <linux/skbuff.h> 12 13 #include <linux/net.h>
+1
net/ipv6/udp.c
··· 17 17 * YOSHIFUJI Hideaki @USAGI: convert /proc/net/udp6 to seq_file. 18 18 */ 19 19 20 + #include <linux/bpf-cgroup.h> 20 21 #include <linux/errno.h> 21 22 #include <linux/types.h> 22 23 #include <linux/socket.h>
+1
net/iucv/af_iucv.c
··· 13 13 #define KMSG_COMPONENT "af_iucv" 14 14 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 15 15 16 + #include <linux/filter.h> 16 17 #include <linux/module.h> 17 18 #include <linux/netdevice.h> 18 19 #include <linux/types.h>
+1
net/kcm/kcmsock.c
··· 9 9 #include <linux/errno.h> 10 10 #include <linux/errqueue.h> 11 11 #include <linux/file.h> 12 + #include <linux/filter.h> 12 13 #include <linux/in.h> 13 14 #include <linux/kernel.h> 14 15 #include <linux/module.h>
+1
net/netfilter/nft_reject_netdev.c
··· 4 4 * Copyright (c) 2020 Jose M. Guisado <guigom@riseup.net> 5 5 */ 6 6 7 + #include <linux/etherdevice.h> 7 8 #include <linux/kernel.h> 8 9 #include <linux/init.h> 9 10 #include <linux/module.h>
+2
net/netlink/af_netlink.c
··· 20 20 21 21 #include <linux/module.h> 22 22 23 + #include <linux/bpf.h> 23 24 #include <linux/capability.h> 24 25 #include <linux/kernel.h> 26 + #include <linux/filter.h> 25 27 #include <linux/init.h> 26 28 #include <linux/signal.h> 27 29 #include <linux/sched.h>
+1
net/packet/af_packet.c
··· 49 49 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 50 50 51 51 #include <linux/ethtool.h> 52 + #include <linux/filter.h> 52 53 #include <linux/types.h> 53 54 #include <linux/mm.h> 54 55 #include <linux/capability.h>
+1
net/rose/rose_in.c
··· 9 9 * diagrams as the code is not obvious and probably very easy to break. 10 10 */ 11 11 #include <linux/errno.h> 12 + #include <linux/filter.h> 12 13 #include <linux/types.h> 13 14 #include <linux/socket.h> 14 15 #include <linux/in.h>
+1
net/sched/sch_frag.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2 + #include <linux/if_vlan.h> 2 3 #include <net/netlink.h> 3 4 #include <net/sch_generic.h> 4 5 #include <net/pkt_sched.h>
+2
net/smc/smc_ib.c
··· 12 12 * Author(s): Ursula Braun <ubraun@linux.vnet.ibm.com> 13 13 */ 14 14 15 + #include <linux/etherdevice.h> 16 + #include <linux/if_vlan.h> 15 17 #include <linux/random.h> 16 18 #include <linux/workqueue.h> 17 19 #include <linux/scatterlist.h>
+1
net/smc/smc_ism.c
··· 6 6 * Copyright IBM Corp. 2018 7 7 */ 8 8 9 + #include <linux/if_vlan.h> 9 10 #include <linux/spinlock.h> 10 11 #include <linux/mutex.h> 11 12 #include <linux/slab.h>
+1
net/socket.c
··· 52 52 * Based upon Swansea University Computer Society NET3.039 53 53 */ 54 54 55 + #include <linux/bpf-cgroup.h> 55 56 #include <linux/ethtool.h> 56 57 #include <linux/mm.h> 57 58 #include <linux/socket.h>
+1
net/unix/af_unix.c
··· 89 89 #include <linux/socket.h> 90 90 #include <linux/un.h> 91 91 #include <linux/fcntl.h> 92 + #include <linux/filter.h> 92 93 #include <linux/termios.h> 93 94 #include <linux/sockios.h> 94 95 #include <linux/net.h>
+1
net/vmw_vsock/af_vsock.c
··· 85 85 * TCP_LISTEN - listening 86 86 */ 87 87 88 + #include <linux/compat.h> 88 89 #include <linux/types.h> 89 90 #include <linux/bitops.h> 90 91 #include <linux/cred.h>
+1
net/xdp/xskmap.c
··· 4 4 */ 5 5 6 6 #include <linux/bpf.h> 7 + #include <linux/filter.h> 7 8 #include <linux/capability.h> 8 9 #include <net/xdp_sock.h> 9 10 #include <linux/slab.h>
+1
net/xfrm/xfrm_state.c
··· 14 14 * 15 15 */ 16 16 17 + #include <linux/compat.h> 17 18 #include <linux/workqueue.h> 18 19 #include <net/xfrm.h> 19 20 #include <linux/pfkeyv2.h>
+1
net/xfrm/xfrm_user.c
··· 11 11 * 12 12 */ 13 13 14 + #include <linux/compat.h> 14 15 #include <linux/crypto.h> 15 16 #include <linux/module.h> 16 17 #include <linux/kernel.h>
+10 -1
samples/bpf/hbm.c
··· 120 120 121 121 static int prog_load(char *prog) 122 122 { 123 + struct bpf_program *pos; 124 + const char *sec_name; 125 + 123 126 obj = bpf_object__open_file(prog, NULL); 124 127 if (libbpf_get_error(obj)) { 125 128 printf("ERROR: opening BPF object file failed\n"); ··· 135 132 goto err; 136 133 } 137 134 138 - bpf_prog = bpf_object__find_program_by_title(obj, "cgroup_skb/egress"); 135 + bpf_object__for_each_program(pos, obj) { 136 + sec_name = bpf_program__section_name(pos); 137 + if (sec_name && !strcmp(sec_name, "cgroup_skb/egress")) { 138 + bpf_prog = pos; 139 + break; 140 + } 141 + } 139 142 if (!bpf_prog) { 140 143 printf("ERROR: finding a prog in obj file failed\n"); 141 144 goto err;
+10 -2
samples/bpf/xdp_fwd_user.c
··· 79 79 .prog_type = BPF_PROG_TYPE_XDP, 80 80 }; 81 81 const char *prog_name = "xdp_fwd"; 82 - struct bpf_program *prog; 82 + struct bpf_program *prog = NULL; 83 + struct bpf_program *pos; 84 + const char *sec_name; 83 85 int prog_fd, map_fd = -1; 84 86 char filename[PATH_MAX]; 85 87 struct bpf_object *obj; ··· 136 134 return 1; 137 135 } 138 136 139 - prog = bpf_object__find_program_by_title(obj, prog_name); 137 + bpf_object__for_each_program(pos, obj) { 138 + sec_name = bpf_program__section_name(pos); 139 + if (sec_name && !strcmp(sec_name, prog_name)) { 140 + prog = pos; 141 + break; 142 + } 143 + } 140 144 prog_fd = bpf_program__fd(prog); 141 145 if (prog_fd < 0) { 142 146 printf("program not found: %s\n", strerror(prog_fd));
+1
security/device_cgroup.c
··· 5 5 * Copyright 2007 IBM Corp 6 6 */ 7 7 8 + #include <linux/bpf-cgroup.h> 8 9 #include <linux/device_cgroup.h> 9 10 #include <linux/cgroup.h> 10 11 #include <linux/ctype.h>
+7 -6
tools/bpf/bpftool/Makefile
··· 57 57 $(LIBBPF_BOOTSTRAP): $(wildcard $(BPF_DIR)/*.[ch] $(BPF_DIR)/Makefile) | $(LIBBPF_BOOTSTRAP_OUTPUT) 58 58 $(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(LIBBPF_BOOTSTRAP_OUTPUT) \ 59 59 DESTDIR=$(LIBBPF_BOOTSTRAP_DESTDIR) prefix= \ 60 - ARCH= CC=$(HOSTCC) LD=$(HOSTLD) $@ install_headers 60 + ARCH= CROSS_COMPILE= CC=$(HOSTCC) LD=$(HOSTLD) $@ install_headers 61 61 62 62 $(LIBBPF_BOOTSTRAP_INTERNAL_HDRS): $(LIBBPF_BOOTSTRAP_HDRS_DIR)/%.h: $(BPF_DIR)/%.h | $(LIBBPF_BOOTSTRAP_HDRS_DIR) 63 63 $(call QUIET_INSTALL, $@) ··· 152 152 SRCS += $(BFD_SRCS) 153 153 endif 154 154 155 + HOST_CFLAGS = $(subst -I$(LIBBPF_INCLUDE),-I$(LIBBPF_BOOTSTRAP_INCLUDE),\ 156 + $(subst $(CLANG_CROSS_FLAGS),,$(CFLAGS))) 157 + 155 158 BPFTOOL_BOOTSTRAP := $(BOOTSTRAP_OUTPUT)bpftool 156 159 157 160 BOOTSTRAP_OBJS = $(addprefix $(BOOTSTRAP_OUTPUT),main.o common.o json_writer.o gen.o btf.o xlated_dumper.o btf_dumper.o disasm.o) ··· 205 202 CFLAGS += $(if $(BUILD_BPF_SKELS),,-DBPFTOOL_WITHOUT_SKELETONS) 206 203 207 204 $(BOOTSTRAP_OUTPUT)disasm.o: $(srctree)/kernel/bpf/disasm.c 208 - $(QUIET_CC)$(HOSTCC) $(CFLAGS) -c -MMD $< -o $@ 205 + $(QUIET_CC)$(HOSTCC) $(HOST_CFLAGS) -c -MMD $< -o $@ 209 206 210 207 $(OUTPUT)disasm.o: $(srctree)/kernel/bpf/disasm.c 211 208 $(QUIET_CC)$(CC) $(CFLAGS) -c -MMD $< -o $@ ··· 216 213 endif 217 214 218 215 $(BPFTOOL_BOOTSTRAP): $(BOOTSTRAP_OBJS) $(LIBBPF_BOOTSTRAP) 219 - $(QUIET_LINK)$(HOSTCC) $(CFLAGS) $(LDFLAGS) $(BOOTSTRAP_OBJS) $(LIBS_BOOTSTRAP) -o $@ 216 + $(QUIET_LINK)$(HOSTCC) $(HOST_CFLAGS) $(LDFLAGS) $(BOOTSTRAP_OBJS) $(LIBS_BOOTSTRAP) -o $@ 220 217 221 218 $(OUTPUT)bpftool: $(OBJS) $(LIBBPF) 222 219 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ 223 220 224 221 $(BOOTSTRAP_OUTPUT)%.o: %.c $(LIBBPF_BOOTSTRAP_INTERNAL_HDRS) | $(BOOTSTRAP_OUTPUT) 225 - $(QUIET_CC)$(HOSTCC) \ 226 - $(subst -I$(LIBBPF_INCLUDE),-I$(LIBBPF_BOOTSTRAP_INCLUDE),$(CFLAGS)) \ 227 - -c -MMD $< -o $@ 222 + $(QUIET_CC)$(HOSTCC) $(HOST_CFLAGS) -c -MMD $< -o $@ 228 223 229 224 $(OUTPUT)%.o: %.c 230 225 $(QUIET_CC)$(CC) $(CFLAGS) -c -MMD $< -o $@
+23 -3
tools/bpf/bpftool/feature.c
··· 642 642 printf("\n"); 643 643 } 644 644 645 - static void 646 - probe_large_insn_limit(const char *define_prefix, __u32 ifindex) 645 + /* 646 + * Probe for availability of kernel commit (5.3): 647 + * 648 + * c04c0d2b968a ("bpf: increase complexity limit and maximum program size") 649 + */ 650 + static void probe_large_insn_limit(const char *define_prefix, __u32 ifindex) 647 651 { 652 + LIBBPF_OPTS(bpf_prog_load_opts, opts, 653 + .prog_ifindex = ifindex, 654 + ); 655 + struct bpf_insn insns[BPF_MAXINSNS + 1]; 648 656 bool res; 657 + int i, fd; 649 658 650 - res = bpf_probe_large_insn_limit(ifindex); 659 + for (i = 0; i < BPF_MAXINSNS; i++) 660 + insns[i] = BPF_MOV64_IMM(BPF_REG_0, 1); 661 + insns[BPF_MAXINSNS] = BPF_EXIT_INSN(); 662 + 663 + errno = 0; 664 + fd = bpf_prog_load(BPF_PROG_TYPE_SCHED_CLS, NULL, "GPL", 665 + insns, ARRAY_SIZE(insns), &opts); 666 + res = fd >= 0 || (errno != E2BIG && errno != EINVAL); 667 + 668 + if (fd >= 0) 669 + close(fd); 670 + 651 671 print_bool_feature("have_large_insn_limit", 652 672 "Large program size limit", 653 673 "LARGE_INSN_LIMIT",
+2
tools/bpf/bpftool/main.c
··· 408 408 bool version_requested = false; 409 409 int opt, ret; 410 410 411 + setlinebuf(stdout); 412 + 411 413 last_do_help = do_help; 412 414 pretty_output = false; 413 415 json_output = false;
+1
tools/bpf/resolve_btfids/Makefile
··· 19 19 LD = $(HOSTLD) 20 20 ARCH = $(HOSTARCH) 21 21 RM ?= rm 22 + CROSS_COMPILE = 22 23 23 24 OUTPUT ?= $(srctree)/tools/bpf/resolve_btfids/ 24 25
+2 -2
tools/bpf/runqslower/Makefile
··· 12 12 BPF_DESTDIR := $(BPFOBJ_OUTPUT) 13 13 BPF_INCLUDE := $(BPF_DESTDIR)/include 14 14 INCLUDES := -I$(OUTPUT) -I$(BPF_INCLUDE) -I$(abspath ../../include/uapi) 15 - CFLAGS := -g -Wall 15 + CFLAGS := -g -Wall $(CLANG_CROSS_FLAGS) 16 16 17 17 # Try to detect best kernel BTF source 18 18 KERNEL_REL := $(shell uname -r) ··· 88 88 89 89 $(DEFAULT_BPFTOOL): $(BPFOBJ) | $(BPFTOOL_OUTPUT) 90 90 $(Q)$(MAKE) $(submake_extras) -C ../bpftool OUTPUT=$(BPFTOOL_OUTPUT) \ 91 - CC=$(HOSTCC) LD=$(HOSTLD) 91 + ARCH= CROSS_COMPILE= CC=$(HOSTCC) LD=$(HOSTLD)
+39
tools/include/uapi/linux/bpf.h
··· 4983 4983 * Return 4984 4984 * The number of loops performed, **-EINVAL** for invalid **flags**, 4985 4985 * **-E2BIG** if **nr_loops** exceeds the maximum number of loops. 4986 + * 4987 + * long bpf_strncmp(const char *s1, u32 s1_sz, const char *s2) 4988 + * Description 4989 + * Do strncmp() between **s1** and **s2**. **s1** doesn't need 4990 + * to be null-terminated and **s1_sz** is the maximum storage 4991 + * size of **s1**. **s2** must be a read-only string. 4992 + * Return 4993 + * An integer less than, equal to, or greater than zero 4994 + * if the first **s1_sz** bytes of **s1** is found to be 4995 + * less than, to match, or be greater than **s2**. 4996 + * 4997 + * long bpf_get_func_arg(void *ctx, u32 n, u64 *value) 4998 + * Description 4999 + * Get **n**-th argument (zero based) of the traced function (for tracing programs) 5000 + * returned in **value**. 5001 + * 5002 + * Return 5003 + * 0 on success. 5004 + * **-EINVAL** if n >= arguments count of traced function. 5005 + * 5006 + * long bpf_get_func_ret(void *ctx, u64 *value) 5007 + * Description 5008 + * Get return value of the traced function (for tracing programs) 5009 + * in **value**. 5010 + * 5011 + * Return 5012 + * 0 on success. 5013 + * **-EOPNOTSUPP** for tracing programs other than BPF_TRACE_FEXIT or BPF_MODIFY_RETURN. 5014 + * 5015 + * long bpf_get_func_arg_cnt(void *ctx) 5016 + * Description 5017 + * Get number of arguments of the traced function (for tracing programs). 5018 + * 5019 + * Return 5020 + * The number of arguments of the traced function. 4986 5021 */ 4987 5022 #define __BPF_FUNC_MAPPER(FN) \ 4988 5023 FN(unspec), \ ··· 5202 5167 FN(kallsyms_lookup_name), \ 5203 5168 FN(find_vma), \ 5204 5169 FN(loop), \ 5170 + FN(strncmp), \ 5171 + FN(get_func_arg), \ 5172 + FN(get_func_ret), \ 5173 + FN(get_func_arg_cnt), \ 5205 5174 /* */ 5206 5175 5207 5176 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
+2 -1
tools/lib/bpf/Makefile
··· 90 90 override CFLAGS += $(INCLUDES) 91 91 override CFLAGS += -fvisibility=hidden 92 92 override CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 93 + override CFLAGS += $(CLANG_CROSS_FLAGS) 93 94 94 95 # flags specific for shared library 95 96 SHLIB_FLAGS := -DSHARED -fPIC ··· 163 162 $(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION) 164 163 165 164 $(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN_SHARED) $(VERSION_SCRIPT) 166 - $(QUIET_LINK)$(CC) $(LDFLAGS) \ 165 + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) \ 167 166 --shared -Wl,-soname,libbpf.so.$(LIBBPF_MAJOR_VERSION) \ 168 167 -Wl,--version-script=$(VERSION_SCRIPT) $< -lelf -lz -o $@ 169 168 @ln -sf $(@F) $(OUTPUT)libbpf.so
+83 -2
tools/lib/bpf/bpf.c
··· 28 28 #include <asm/unistd.h> 29 29 #include <errno.h> 30 30 #include <linux/bpf.h> 31 + #include <linux/filter.h> 31 32 #include <limits.h> 33 + #include <sys/resource.h> 32 34 #include "bpf.h" 33 35 #include "libbpf.h" 34 36 #include "libbpf_internal.h" ··· 96 94 return fd; 97 95 } 98 96 97 + /* Probe whether kernel switched from memlock-based (RLIMIT_MEMLOCK) to 98 + * memcg-based memory accounting for BPF maps and progs. This was done in [0]. 99 + * We use the support for bpf_ktime_get_coarse_ns() helper, which was added in 100 + * the same 5.11 Linux release ([1]), to detect memcg-based accounting for BPF. 101 + * 102 + * [0] https://lore.kernel.org/bpf/20201201215900.3569844-1-guro@fb.com/ 103 + * [1] d05512618056 ("bpf: Add bpf_ktime_get_coarse_ns helper") 104 + */ 105 + int probe_memcg_account(void) 106 + { 107 + const size_t prog_load_attr_sz = offsetofend(union bpf_attr, attach_btf_obj_fd); 108 + struct bpf_insn insns[] = { 109 + BPF_EMIT_CALL(BPF_FUNC_ktime_get_coarse_ns), 110 + BPF_EXIT_INSN(), 111 + }; 112 + size_t insn_cnt = sizeof(insns) / sizeof(insns[0]); 113 + union bpf_attr attr; 114 + int prog_fd; 115 + 116 + /* attempt loading freplace trying to use custom BTF */ 117 + memset(&attr, 0, prog_load_attr_sz); 118 + attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER; 119 + attr.insns = ptr_to_u64(insns); 120 + attr.insn_cnt = insn_cnt; 121 + attr.license = ptr_to_u64("GPL"); 122 + 123 + prog_fd = sys_bpf_fd(BPF_PROG_LOAD, &attr, prog_load_attr_sz); 124 + if (prog_fd >= 0) { 125 + close(prog_fd); 126 + return 1; 127 + } 128 + return 0; 129 + } 130 + 131 + static bool memlock_bumped; 132 + static rlim_t memlock_rlim = RLIM_INFINITY; 133 + 134 + int libbpf_set_memlock_rlim(size_t memlock_bytes) 135 + { 136 + if (memlock_bumped) 137 + return libbpf_err(-EBUSY); 138 + 139 + memlock_rlim = memlock_bytes; 140 + return 0; 141 + } 142 + 143 + int bump_rlimit_memlock(void) 144 + { 145 + struct rlimit rlim; 146 + 147 + /* this the default in libbpf 1.0, but for now user has to opt-in explicitly */ 148 + if (!(libbpf_mode & LIBBPF_STRICT_AUTO_RLIMIT_MEMLOCK)) 149 + return 0; 150 + 151 + /* if kernel supports memcg-based accounting, skip bumping RLIMIT_MEMLOCK */ 152 + if (memlock_bumped || kernel_supports(NULL, FEAT_MEMCG_ACCOUNT)) 153 + return 0; 154 + 155 + memlock_bumped = true; 156 + 157 + /* zero memlock_rlim_max disables auto-bumping RLIMIT_MEMLOCK */ 158 + if (memlock_rlim == 0) 159 + return 0; 160 + 161 + rlim.rlim_cur = rlim.rlim_max = memlock_rlim; 162 + if (setrlimit(RLIMIT_MEMLOCK, &rlim)) 163 + return -errno; 164 + 165 + return 0; 166 + } 167 + 99 168 int bpf_map_create(enum bpf_map_type map_type, 100 169 const char *map_name, 101 170 __u32 key_size, ··· 178 105 union bpf_attr attr; 179 106 int fd; 180 107 108 + bump_rlimit_memlock(); 109 + 181 110 memset(&attr, 0, attr_sz); 182 111 183 112 if (!OPTS_VALID(opts, bpf_map_create_opts)) ··· 187 112 188 113 attr.map_type = map_type; 189 114 if (map_name) 190 - strncat(attr.map_name, map_name, sizeof(attr.map_name) - 1); 115 + libbpf_strlcpy(attr.map_name, map_name, sizeof(attr.map_name)); 191 116 attr.key_size = key_size; 192 117 attr.value_size = value_size; 193 118 attr.max_entries = max_entries; ··· 326 251 union bpf_attr attr; 327 252 char *log_buf; 328 253 254 + bump_rlimit_memlock(); 255 + 329 256 if (!OPTS_VALID(opts, bpf_prog_load_opts)) 330 257 return libbpf_err(-EINVAL); 331 258 ··· 348 271 attr.kern_version = OPTS_GET(opts, kern_version, 0); 349 272 350 273 if (prog_name) 351 - strncat(attr.prog_name, prog_name, sizeof(attr.prog_name) - 1); 274 + libbpf_strlcpy(attr.prog_name, prog_name, sizeof(attr.prog_name)); 352 275 attr.license = ptr_to_u64(license); 353 276 354 277 if (insn_cnt > UINT_MAX) ··· 532 455 { 533 456 union bpf_attr attr; 534 457 int fd; 458 + 459 + bump_rlimit_memlock(); 535 460 536 461 memset(&attr, 0, sizeof(attr)); 537 462 attr.prog_type = type; ··· 1134 1055 size_t log_size; 1135 1056 __u32 log_level; 1136 1057 int fd; 1058 + 1059 + bump_rlimit_memlock(); 1137 1060 1138 1061 memset(&attr, 0, attr_sz); 1139 1062
+2
tools/lib/bpf/bpf.h
··· 35 35 extern "C" { 36 36 #endif 37 37 38 + int libbpf_set_memlock_rlim(size_t memlock_bytes); 39 + 38 40 struct bpf_map_create_opts { 39 41 size_t sz; /* size of this struct for forward/backward compatibility */ 40 42
+171 -254
tools/lib/bpf/bpf_tracing.h
··· 66 66 67 67 #if defined(__KERNEL__) || defined(__VMLINUX_H__) 68 68 69 - #define PT_REGS_PARM1(x) ((x)->di) 70 - #define PT_REGS_PARM2(x) ((x)->si) 71 - #define PT_REGS_PARM3(x) ((x)->dx) 72 - #define PT_REGS_PARM4(x) ((x)->cx) 73 - #define PT_REGS_PARM5(x) ((x)->r8) 74 - #define PT_REGS_RET(x) ((x)->sp) 75 - #define PT_REGS_FP(x) ((x)->bp) 76 - #define PT_REGS_RC(x) ((x)->ax) 77 - #define PT_REGS_SP(x) ((x)->sp) 78 - #define PT_REGS_IP(x) ((x)->ip) 79 - 80 - #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), di) 81 - #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), si) 82 - #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), dx) 83 - #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), cx) 84 - #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), r8) 85 - #define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), sp) 86 - #define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), bp) 87 - #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), ax) 88 - #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), sp) 89 - #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), ip) 69 + #define __PT_PARM1_REG di 70 + #define __PT_PARM2_REG si 71 + #define __PT_PARM3_REG dx 72 + #define __PT_PARM4_REG cx 73 + #define __PT_PARM5_REG r8 74 + #define __PT_RET_REG sp 75 + #define __PT_FP_REG bp 76 + #define __PT_RC_REG ax 77 + #define __PT_SP_REG sp 78 + #define __PT_IP_REG ip 90 79 91 80 #else 92 81 93 82 #ifdef __i386__ 83 + 84 + #define __PT_PARM1_REG eax 85 + #define __PT_PARM2_REG edx 86 + #define __PT_PARM3_REG ecx 94 87 /* i386 kernel is built with -mregparm=3 */ 95 - #define PT_REGS_PARM1(x) ((x)->eax) 96 - #define PT_REGS_PARM2(x) ((x)->edx) 97 - #define PT_REGS_PARM3(x) ((x)->ecx) 98 - #define PT_REGS_PARM4(x) 0 99 - #define PT_REGS_PARM5(x) 0 100 - #define PT_REGS_RET(x) ((x)->esp) 101 - #define PT_REGS_FP(x) ((x)->ebp) 102 - #define PT_REGS_RC(x) ((x)->eax) 103 - #define PT_REGS_SP(x) ((x)->esp) 104 - #define PT_REGS_IP(x) ((x)->eip) 88 + #define __PT_PARM4_REG __unsupported__ 89 + #define __PT_PARM5_REG __unsupported__ 90 + #define __PT_RET_REG esp 91 + #define __PT_FP_REG ebp 92 + #define __PT_RC_REG eax 93 + #define __PT_SP_REG esp 94 + #define __PT_IP_REG eip 105 95 106 - #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), eax) 107 - #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), edx) 108 - #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), ecx) 109 - #define PT_REGS_PARM4_CORE(x) 0 110 - #define PT_REGS_PARM5_CORE(x) 0 111 - #define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), esp) 112 - #define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), ebp) 113 - #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), eax) 114 - #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), esp) 115 - #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), eip) 96 + #else /* __i386__ */ 116 97 117 - #else 98 + #define __PT_PARM1_REG rdi 99 + #define __PT_PARM2_REG rsi 100 + #define __PT_PARM3_REG rdx 101 + #define __PT_PARM4_REG rcx 102 + #define __PT_PARM5_REG r8 103 + #define __PT_RET_REG rsp 104 + #define __PT_FP_REG rbp 105 + #define __PT_RC_REG rax 106 + #define __PT_SP_REG rsp 107 + #define __PT_IP_REG rip 118 108 119 - #define PT_REGS_PARM1(x) ((x)->rdi) 120 - #define PT_REGS_PARM2(x) ((x)->rsi) 121 - #define PT_REGS_PARM3(x) ((x)->rdx) 122 - #define PT_REGS_PARM4(x) ((x)->rcx) 123 - #define PT_REGS_PARM5(x) ((x)->r8) 124 - #define PT_REGS_RET(x) ((x)->rsp) 125 - #define PT_REGS_FP(x) ((x)->rbp) 126 - #define PT_REGS_RC(x) ((x)->rax) 127 - #define PT_REGS_SP(x) ((x)->rsp) 128 - #define PT_REGS_IP(x) ((x)->rip) 109 + #endif /* __i386__ */ 129 110 130 - #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), rdi) 131 - #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), rsi) 132 - #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), rdx) 133 - #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), rcx) 134 - #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), r8) 135 - #define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), rsp) 136 - #define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), rbp) 137 - #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), rax) 138 - #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), rsp) 139 - #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), rip) 140 - 141 - #endif 142 - #endif 111 + #endif /* __KERNEL__ || __VMLINUX_H__ */ 143 112 144 113 #elif defined(bpf_target_s390) 145 114 146 115 /* s390 provides user_pt_regs instead of struct pt_regs to userspace */ 147 - struct pt_regs; 148 - #define PT_REGS_S390 const volatile user_pt_regs 149 - #define PT_REGS_PARM1(x) (((PT_REGS_S390 *)(x))->gprs[2]) 150 - #define PT_REGS_PARM2(x) (((PT_REGS_S390 *)(x))->gprs[3]) 151 - #define PT_REGS_PARM3(x) (((PT_REGS_S390 *)(x))->gprs[4]) 152 - #define PT_REGS_PARM4(x) (((PT_REGS_S390 *)(x))->gprs[5]) 153 - #define PT_REGS_PARM5(x) (((PT_REGS_S390 *)(x))->gprs[6]) 154 - #define PT_REGS_RET(x) (((PT_REGS_S390 *)(x))->gprs[14]) 155 - /* Works only with CONFIG_FRAME_POINTER */ 156 - #define PT_REGS_FP(x) (((PT_REGS_S390 *)(x))->gprs[11]) 157 - #define PT_REGS_RC(x) (((PT_REGS_S390 *)(x))->gprs[2]) 158 - #define PT_REGS_SP(x) (((PT_REGS_S390 *)(x))->gprs[15]) 159 - #define PT_REGS_IP(x) (((PT_REGS_S390 *)(x))->psw.addr) 160 - 161 - #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[2]) 162 - #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[3]) 163 - #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[4]) 164 - #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[5]) 165 - #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[6]) 166 - #define PT_REGS_RET_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[14]) 167 - #define PT_REGS_FP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[11]) 168 - #define PT_REGS_RC_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[2]) 169 - #define PT_REGS_SP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), gprs[15]) 170 - #define PT_REGS_IP_CORE(x) BPF_CORE_READ((PT_REGS_S390 *)(x), psw.addr) 116 + #define __PT_REGS_CAST(x) ((const user_pt_regs *)(x)) 117 + #define __PT_PARM1_REG gprs[2] 118 + #define __PT_PARM2_REG gprs[3] 119 + #define __PT_PARM3_REG gprs[4] 120 + #define __PT_PARM4_REG gprs[5] 121 + #define __PT_PARM5_REG gprs[6] 122 + #define __PT_RET_REG grps[14] 123 + #define __PT_FP_REG gprs[11] /* Works only with CONFIG_FRAME_POINTER */ 124 + #define __PT_RC_REG gprs[2] 125 + #define __PT_SP_REG gprs[15] 126 + #define __PT_IP_REG psw.addr 171 127 172 128 #elif defined(bpf_target_arm) 173 129 174 - #define PT_REGS_PARM1(x) ((x)->uregs[0]) 175 - #define PT_REGS_PARM2(x) ((x)->uregs[1]) 176 - #define PT_REGS_PARM3(x) ((x)->uregs[2]) 177 - #define PT_REGS_PARM4(x) ((x)->uregs[3]) 178 - #define PT_REGS_PARM5(x) ((x)->uregs[4]) 179 - #define PT_REGS_RET(x) ((x)->uregs[14]) 180 - #define PT_REGS_FP(x) ((x)->uregs[11]) /* Works only with CONFIG_FRAME_POINTER */ 181 - #define PT_REGS_RC(x) ((x)->uregs[0]) 182 - #define PT_REGS_SP(x) ((x)->uregs[13]) 183 - #define PT_REGS_IP(x) ((x)->uregs[12]) 184 - 185 - #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), uregs[0]) 186 - #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), uregs[1]) 187 - #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), uregs[2]) 188 - #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), uregs[3]) 189 - #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), uregs[4]) 190 - #define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), uregs[14]) 191 - #define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), uregs[11]) 192 - #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), uregs[0]) 193 - #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), uregs[13]) 194 - #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), uregs[12]) 130 + #define __PT_PARM1_REG uregs[0] 131 + #define __PT_PARM2_REG uregs[1] 132 + #define __PT_PARM3_REG uregs[2] 133 + #define __PT_PARM4_REG uregs[3] 134 + #define __PT_PARM5_REG uregs[4] 135 + #define __PT_RET_REG uregs[14] 136 + #define __PT_FP_REG uregs[11] /* Works only with CONFIG_FRAME_POINTER */ 137 + #define __PT_RC_REG uregs[0] 138 + #define __PT_SP_REG uregs[13] 139 + #define __PT_IP_REG uregs[12] 195 140 196 141 #elif defined(bpf_target_arm64) 197 142 198 143 /* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */ 199 - struct pt_regs; 200 - #define PT_REGS_ARM64 const volatile struct user_pt_regs 201 - #define PT_REGS_PARM1(x) (((PT_REGS_ARM64 *)(x))->regs[0]) 202 - #define PT_REGS_PARM2(x) (((PT_REGS_ARM64 *)(x))->regs[1]) 203 - #define PT_REGS_PARM3(x) (((PT_REGS_ARM64 *)(x))->regs[2]) 204 - #define PT_REGS_PARM4(x) (((PT_REGS_ARM64 *)(x))->regs[3]) 205 - #define PT_REGS_PARM5(x) (((PT_REGS_ARM64 *)(x))->regs[4]) 206 - #define PT_REGS_RET(x) (((PT_REGS_ARM64 *)(x))->regs[30]) 207 - /* Works only with CONFIG_FRAME_POINTER */ 208 - #define PT_REGS_FP(x) (((PT_REGS_ARM64 *)(x))->regs[29]) 209 - #define PT_REGS_RC(x) (((PT_REGS_ARM64 *)(x))->regs[0]) 210 - #define PT_REGS_SP(x) (((PT_REGS_ARM64 *)(x))->sp) 211 - #define PT_REGS_IP(x) (((PT_REGS_ARM64 *)(x))->pc) 212 - 213 - #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[0]) 214 - #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[1]) 215 - #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[2]) 216 - #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[3]) 217 - #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[4]) 218 - #define PT_REGS_RET_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[30]) 219 - #define PT_REGS_FP_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[29]) 220 - #define PT_REGS_RC_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), regs[0]) 221 - #define PT_REGS_SP_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), sp) 222 - #define PT_REGS_IP_CORE(x) BPF_CORE_READ((PT_REGS_ARM64 *)(x), pc) 144 + #define __PT_REGS_CAST(x) ((const struct user_pt_regs *)(x)) 145 + #define __PT_PARM1_REG regs[0] 146 + #define __PT_PARM2_REG regs[1] 147 + #define __PT_PARM3_REG regs[2] 148 + #define __PT_PARM4_REG regs[3] 149 + #define __PT_PARM5_REG regs[4] 150 + #define __PT_RET_REG regs[30] 151 + #define __PT_FP_REG regs[29] /* Works only with CONFIG_FRAME_POINTER */ 152 + #define __PT_RC_REG regs[0] 153 + #define __PT_SP_REG sp 154 + #define __PT_IP_REG pc 223 155 224 156 #elif defined(bpf_target_mips) 225 157 226 - #define PT_REGS_PARM1(x) ((x)->regs[4]) 227 - #define PT_REGS_PARM2(x) ((x)->regs[5]) 228 - #define PT_REGS_PARM3(x) ((x)->regs[6]) 229 - #define PT_REGS_PARM4(x) ((x)->regs[7]) 230 - #define PT_REGS_PARM5(x) ((x)->regs[8]) 231 - #define PT_REGS_RET(x) ((x)->regs[31]) 232 - #define PT_REGS_FP(x) ((x)->regs[30]) /* Works only with CONFIG_FRAME_POINTER */ 233 - #define PT_REGS_RC(x) ((x)->regs[2]) 234 - #define PT_REGS_SP(x) ((x)->regs[29]) 235 - #define PT_REGS_IP(x) ((x)->cp0_epc) 236 - 237 - #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), regs[4]) 238 - #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), regs[5]) 239 - #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), regs[6]) 240 - #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), regs[7]) 241 - #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), regs[8]) 242 - #define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), regs[31]) 243 - #define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), regs[30]) 244 - #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), regs[2]) 245 - #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), regs[29]) 246 - #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), cp0_epc) 158 + #define __PT_PARM1_REG regs[4] 159 + #define __PT_PARM2_REG regs[5] 160 + #define __PT_PARM3_REG regs[6] 161 + #define __PT_PARM4_REG regs[7] 162 + #define __PT_PARM5_REG regs[8] 163 + #define __PT_RET_REG regs[31] 164 + #define __PT_FP_REG regs[30] /* Works only with CONFIG_FRAME_POINTER */ 165 + #define __PT_RC_REG regs[2] 166 + #define __PT_SP_REG regs[29] 167 + #define __PT_IP_REG cp0_epc 247 168 248 169 #elif defined(bpf_target_powerpc) 249 170 250 - #define PT_REGS_PARM1(x) ((x)->gpr[3]) 251 - #define PT_REGS_PARM2(x) ((x)->gpr[4]) 252 - #define PT_REGS_PARM3(x) ((x)->gpr[5]) 253 - #define PT_REGS_PARM4(x) ((x)->gpr[6]) 254 - #define PT_REGS_PARM5(x) ((x)->gpr[7]) 255 - #define PT_REGS_RC(x) ((x)->gpr[3]) 256 - #define PT_REGS_SP(x) ((x)->sp) 257 - #define PT_REGS_IP(x) ((x)->nip) 258 - 259 - #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), gpr[3]) 260 - #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), gpr[4]) 261 - #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), gpr[5]) 262 - #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), gpr[6]) 263 - #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), gpr[7]) 264 - #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), gpr[3]) 265 - #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), sp) 266 - #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), nip) 171 + #define __PT_PARM1_REG gpr[3] 172 + #define __PT_PARM2_REG gpr[4] 173 + #define __PT_PARM3_REG gpr[5] 174 + #define __PT_PARM4_REG gpr[6] 175 + #define __PT_PARM5_REG gpr[7] 176 + #define __PT_RET_REG regs[31] 177 + #define __PT_FP_REG __unsupported__ 178 + #define __PT_RC_REG gpr[3] 179 + #define __PT_SP_REG sp 180 + #define __PT_IP_REG nip 267 181 268 182 #elif defined(bpf_target_sparc) 269 183 270 - #define PT_REGS_PARM1(x) ((x)->u_regs[UREG_I0]) 271 - #define PT_REGS_PARM2(x) ((x)->u_regs[UREG_I1]) 272 - #define PT_REGS_PARM3(x) ((x)->u_regs[UREG_I2]) 273 - #define PT_REGS_PARM4(x) ((x)->u_regs[UREG_I3]) 274 - #define PT_REGS_PARM5(x) ((x)->u_regs[UREG_I4]) 275 - #define PT_REGS_RET(x) ((x)->u_regs[UREG_I7]) 276 - #define PT_REGS_RC(x) ((x)->u_regs[UREG_I0]) 277 - #define PT_REGS_SP(x) ((x)->u_regs[UREG_FP]) 278 - 279 - #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I0]) 280 - #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I1]) 281 - #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I2]) 282 - #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I3]) 283 - #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I4]) 284 - #define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I7]) 285 - #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), u_regs[UREG_I0]) 286 - #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), u_regs[UREG_FP]) 287 - 184 + #define __PT_PARM1_REG u_regs[UREG_I0] 185 + #define __PT_PARM2_REG u_regs[UREG_I1] 186 + #define __PT_PARM3_REG u_regs[UREG_I2] 187 + #define __PT_PARM4_REG u_regs[UREG_I3] 188 + #define __PT_PARM5_REG u_regs[UREG_I4] 189 + #define __PT_RET_REG u_regs[UREG_I7] 190 + #define __PT_FP_REG __unsupported__ 191 + #define __PT_RC_REG u_regs[UREG_I0] 192 + #define __PT_SP_REG u_regs[UREG_FP] 288 193 /* Should this also be a bpf_target check for the sparc case? */ 289 194 #if defined(__arch64__) 290 - #define PT_REGS_IP(x) ((x)->tpc) 291 - #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), tpc) 195 + #define __PT_IP_REG tpc 292 196 #else 293 - #define PT_REGS_IP(x) ((x)->pc) 294 - #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), pc) 197 + #define __PT_IP_REG pc 295 198 #endif 296 199 297 200 #elif defined(bpf_target_riscv) 298 201 299 - struct pt_regs; 300 - #define PT_REGS_RV const volatile struct user_regs_struct 301 - #define PT_REGS_PARM1(x) (((PT_REGS_RV *)(x))->a0) 302 - #define PT_REGS_PARM2(x) (((PT_REGS_RV *)(x))->a1) 303 - #define PT_REGS_PARM3(x) (((PT_REGS_RV *)(x))->a2) 304 - #define PT_REGS_PARM4(x) (((PT_REGS_RV *)(x))->a3) 305 - #define PT_REGS_PARM5(x) (((PT_REGS_RV *)(x))->a4) 306 - #define PT_REGS_RET(x) (((PT_REGS_RV *)(x))->ra) 307 - #define PT_REGS_FP(x) (((PT_REGS_RV *)(x))->s5) 308 - #define PT_REGS_RC(x) (((PT_REGS_RV *)(x))->a5) 309 - #define PT_REGS_SP(x) (((PT_REGS_RV *)(x))->sp) 310 - #define PT_REGS_IP(x) (((PT_REGS_RV *)(x))->epc) 311 - 312 - #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a0) 313 - #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a1) 314 - #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a2) 315 - #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a3) 316 - #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a4) 317 - #define PT_REGS_RET_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), ra) 318 - #define PT_REGS_FP_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), fp) 319 - #define PT_REGS_RC_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), a5) 320 - #define PT_REGS_SP_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), sp) 321 - #define PT_REGS_IP_CORE(x) BPF_CORE_READ((PT_REGS_RV *)(x), epc) 202 + #define __PT_REGS_CAST(x) ((const struct user_regs_struct *)(x)) 203 + #define __PT_PARM1_REG a0 204 + #define __PT_PARM2_REG a1 205 + #define __PT_PARM3_REG a2 206 + #define __PT_PARM4_REG a3 207 + #define __PT_PARM5_REG a4 208 + #define __PT_RET_REG ra 209 + #define __PT_FP_REG fp 210 + #define __PT_RC_REG a5 211 + #define __PT_SP_REG sp 212 + #define __PT_IP_REG epc 322 213 323 214 #endif 324 215 216 + #if defined(bpf_target_defined) 217 + 218 + struct pt_regs; 219 + 220 + /* allow some architecutres to override `struct pt_regs` */ 221 + #ifndef __PT_REGS_CAST 222 + #define __PT_REGS_CAST(x) (x) 223 + #endif 224 + 225 + #define PT_REGS_PARM1(x) (__PT_REGS_CAST(x)->__PT_PARM1_REG) 226 + #define PT_REGS_PARM2(x) (__PT_REGS_CAST(x)->__PT_PARM2_REG) 227 + #define PT_REGS_PARM3(x) (__PT_REGS_CAST(x)->__PT_PARM3_REG) 228 + #define PT_REGS_PARM4(x) (__PT_REGS_CAST(x)->__PT_PARM4_REG) 229 + #define PT_REGS_PARM5(x) (__PT_REGS_CAST(x)->__PT_PARM5_REG) 230 + #define PT_REGS_RET(x) (__PT_REGS_CAST(x)->__PT_RET_REG) 231 + #define PT_REGS_FP(x) (__PT_REGS_CAST(x)->__PT_FP_REG) 232 + #define PT_REGS_RC(x) (__PT_REGS_CAST(x)->__PT_RC_REG) 233 + #define PT_REGS_SP(x) (__PT_REGS_CAST(x)->__PT_SP_REG) 234 + #define PT_REGS_IP(x) (__PT_REGS_CAST(x)->__PT_IP_REG) 235 + 236 + #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM1_REG) 237 + #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM2_REG) 238 + #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM3_REG) 239 + #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM4_REG) 240 + #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM5_REG) 241 + #define PT_REGS_RET_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_RET_REG) 242 + #define PT_REGS_FP_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_FP_REG) 243 + #define PT_REGS_RC_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_RC_REG) 244 + #define PT_REGS_SP_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_SP_REG) 245 + #define PT_REGS_IP_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_IP_REG) 246 + 325 247 #if defined(bpf_target_powerpc) 248 + 326 249 #define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = (ctx)->link; }) 327 250 #define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP 251 + 328 252 #elif defined(bpf_target_sparc) 253 + 329 254 #define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ (ip) = PT_REGS_RET(ctx); }) 330 255 #define BPF_KRETPROBE_READ_RET_IP BPF_KPROBE_READ_RET_IP 331 - #elif defined(bpf_target_defined) 256 + 257 + #else 258 + 332 259 #define BPF_KPROBE_READ_RET_IP(ip, ctx) \ 333 260 ({ bpf_probe_read_kernel(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); }) 334 261 #define BPF_KRETPROBE_READ_RET_IP(ip, ctx) \ 335 - ({ bpf_probe_read_kernel(&(ip), sizeof(ip), \ 336 - (void *)(PT_REGS_FP(ctx) + sizeof(ip))); }) 262 + ({ bpf_probe_read_kernel(&(ip), sizeof(ip), (void *)(PT_REGS_FP(ctx) + sizeof(ip))); }) 263 + 337 264 #endif 338 265 339 - #if !defined(bpf_target_defined) 266 + #else /* defined(bpf_target_defined) */ 340 267 341 268 #define PT_REGS_PARM1(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 342 269 #define PT_REGS_PARM2(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) ··· 290 363 #define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 291 364 #define BPF_KRETPROBE_READ_RET_IP(ip, ctx) ({ _Pragma(__BPF_TARGET_MISSING); 0l; }) 292 365 293 - #endif /* !defined(bpf_target_defined) */ 366 + #endif /* defined(bpf_target_defined) */ 294 367 295 368 #ifndef ___bpf_concat 296 369 #define ___bpf_concat(a, b) a ## b ··· 302 375 #define ___bpf_nth(_, _1, _2, _3, _4, _5, _6, _7, _8, _9, _a, _b, _c, N, ...) N 303 376 #endif 304 377 #ifndef ___bpf_narg 305 - #define ___bpf_narg(...) \ 306 - ___bpf_nth(_, ##__VA_ARGS__, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) 378 + #define ___bpf_narg(...) ___bpf_nth(_, ##__VA_ARGS__, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) 307 379 #endif 308 380 309 - #define ___bpf_ctx_cast0() ctx 310 - #define ___bpf_ctx_cast1(x) ___bpf_ctx_cast0(), (void *)ctx[0] 311 - #define ___bpf_ctx_cast2(x, args...) ___bpf_ctx_cast1(args), (void *)ctx[1] 312 - #define ___bpf_ctx_cast3(x, args...) ___bpf_ctx_cast2(args), (void *)ctx[2] 313 - #define ___bpf_ctx_cast4(x, args...) ___bpf_ctx_cast3(args), (void *)ctx[3] 314 - #define ___bpf_ctx_cast5(x, args...) ___bpf_ctx_cast4(args), (void *)ctx[4] 315 - #define ___bpf_ctx_cast6(x, args...) ___bpf_ctx_cast5(args), (void *)ctx[5] 316 - #define ___bpf_ctx_cast7(x, args...) ___bpf_ctx_cast6(args), (void *)ctx[6] 317 - #define ___bpf_ctx_cast8(x, args...) ___bpf_ctx_cast7(args), (void *)ctx[7] 318 - #define ___bpf_ctx_cast9(x, args...) ___bpf_ctx_cast8(args), (void *)ctx[8] 381 + #define ___bpf_ctx_cast0() ctx 382 + #define ___bpf_ctx_cast1(x) ___bpf_ctx_cast0(), (void *)ctx[0] 383 + #define ___bpf_ctx_cast2(x, args...) ___bpf_ctx_cast1(args), (void *)ctx[1] 384 + #define ___bpf_ctx_cast3(x, args...) ___bpf_ctx_cast2(args), (void *)ctx[2] 385 + #define ___bpf_ctx_cast4(x, args...) ___bpf_ctx_cast3(args), (void *)ctx[3] 386 + #define ___bpf_ctx_cast5(x, args...) ___bpf_ctx_cast4(args), (void *)ctx[4] 387 + #define ___bpf_ctx_cast6(x, args...) ___bpf_ctx_cast5(args), (void *)ctx[5] 388 + #define ___bpf_ctx_cast7(x, args...) ___bpf_ctx_cast6(args), (void *)ctx[6] 389 + #define ___bpf_ctx_cast8(x, args...) ___bpf_ctx_cast7(args), (void *)ctx[7] 390 + #define ___bpf_ctx_cast9(x, args...) ___bpf_ctx_cast8(args), (void *)ctx[8] 319 391 #define ___bpf_ctx_cast10(x, args...) ___bpf_ctx_cast9(args), (void *)ctx[9] 320 392 #define ___bpf_ctx_cast11(x, args...) ___bpf_ctx_cast10(args), (void *)ctx[10] 321 393 #define ___bpf_ctx_cast12(x, args...) ___bpf_ctx_cast11(args), (void *)ctx[11] 322 - #define ___bpf_ctx_cast(args...) \ 323 - ___bpf_apply(___bpf_ctx_cast, ___bpf_narg(args))(args) 394 + #define ___bpf_ctx_cast(args...) ___bpf_apply(___bpf_ctx_cast, ___bpf_narg(args))(args) 324 395 325 396 /* 326 397 * BPF_PROG is a convenience wrapper for generic tp_btf/fentry/fexit and ··· 351 426 352 427 struct pt_regs; 353 428 354 - #define ___bpf_kprobe_args0() ctx 355 - #define ___bpf_kprobe_args1(x) \ 356 - ___bpf_kprobe_args0(), (void *)PT_REGS_PARM1(ctx) 357 - #define ___bpf_kprobe_args2(x, args...) \ 358 - ___bpf_kprobe_args1(args), (void *)PT_REGS_PARM2(ctx) 359 - #define ___bpf_kprobe_args3(x, args...) \ 360 - ___bpf_kprobe_args2(args), (void *)PT_REGS_PARM3(ctx) 361 - #define ___bpf_kprobe_args4(x, args...) \ 362 - ___bpf_kprobe_args3(args), (void *)PT_REGS_PARM4(ctx) 363 - #define ___bpf_kprobe_args5(x, args...) \ 364 - ___bpf_kprobe_args4(args), (void *)PT_REGS_PARM5(ctx) 365 - #define ___bpf_kprobe_args(args...) \ 366 - ___bpf_apply(___bpf_kprobe_args, ___bpf_narg(args))(args) 429 + #define ___bpf_kprobe_args0() ctx 430 + #define ___bpf_kprobe_args1(x) ___bpf_kprobe_args0(), (void *)PT_REGS_PARM1(ctx) 431 + #define ___bpf_kprobe_args2(x, args...) ___bpf_kprobe_args1(args), (void *)PT_REGS_PARM2(ctx) 432 + #define ___bpf_kprobe_args3(x, args...) ___bpf_kprobe_args2(args), (void *)PT_REGS_PARM3(ctx) 433 + #define ___bpf_kprobe_args4(x, args...) ___bpf_kprobe_args3(args), (void *)PT_REGS_PARM4(ctx) 434 + #define ___bpf_kprobe_args5(x, args...) ___bpf_kprobe_args4(args), (void *)PT_REGS_PARM5(ctx) 435 + #define ___bpf_kprobe_args(args...) ___bpf_apply(___bpf_kprobe_args, ___bpf_narg(args))(args) 367 436 368 437 /* 369 438 * BPF_KPROBE serves the same purpose for kprobes as BPF_PROG for ··· 383 464 static __attribute__((always_inline)) typeof(name(0)) \ 384 465 ____##name(struct pt_regs *ctx, ##args) 385 466 386 - #define ___bpf_kretprobe_args0() ctx 387 - #define ___bpf_kretprobe_args1(x) \ 388 - ___bpf_kretprobe_args0(), (void *)PT_REGS_RC(ctx) 389 - #define ___bpf_kretprobe_args(args...) \ 390 - ___bpf_apply(___bpf_kretprobe_args, ___bpf_narg(args))(args) 467 + #define ___bpf_kretprobe_args0() ctx 468 + #define ___bpf_kretprobe_args1(x) ___bpf_kretprobe_args0(), (void *)PT_REGS_RC(ctx) 469 + #define ___bpf_kretprobe_args(args...) ___bpf_apply(___bpf_kretprobe_args, ___bpf_narg(args))(args) 391 470 392 471 /* 393 472 * BPF_KRETPROBE is similar to BPF_KPROBE, except, it only provides optional
+6
tools/lib/bpf/btf.h
··· 313 313 * 314 314 * The rest works just like in case of ___libbpf_override() usage with symbol 315 315 * versioning. 316 + * 317 + * C++ compilers don't support __builtin_types_compatible_p(), so at least 318 + * don't screw up compilation for them and let C++ users pick btf_dump__new 319 + * vs btf_dump__new_deprecated explicitly. 316 320 */ 321 + #ifndef __cplusplus 317 322 #define btf_dump__new(a1, a2, a3, a4) __builtin_choose_expr( \ 318 323 __builtin_types_compatible_p(typeof(a4), btf_dump_printf_fn_t) || \ 319 324 __builtin_types_compatible_p(typeof(a4), void(void *, const char *, va_list)), \ 320 325 btf_dump__new_deprecated((void *)a1, (void *)a2, (void *)a3, (void *)a4), \ 321 326 btf_dump__new((void *)a1, (void *)a2, (void *)a3, (void *)a4)) 327 + #endif 322 328 323 329 LIBBPF_API void btf_dump__free(struct btf_dump *d); 324 330
+2 -2
tools/lib/bpf/btf_dump.c
··· 2321 2321 if (!opts->indent_str) 2322 2322 d->typed_dump->indent_str[0] = '\t'; 2323 2323 else 2324 - strncat(d->typed_dump->indent_str, opts->indent_str, 2325 - sizeof(d->typed_dump->indent_str) - 1); 2324 + libbpf_strlcpy(d->typed_dump->indent_str, opts->indent_str, 2325 + sizeof(d->typed_dump->indent_str)); 2326 2326 2327 2327 d->typed_dump->compact = OPTS_GET(opts, compact, false); 2328 2328 d->typed_dump->skip_names = OPTS_GET(opts, skip_names, false);
+5 -6
tools/lib/bpf/gen_loader.c
··· 371 371 { 372 372 int i; 373 373 374 - if (nr_progs != gen->nr_progs || nr_maps != gen->nr_maps) { 375 - pr_warn("progs/maps mismatch\n"); 374 + if (nr_progs < gen->nr_progs || nr_maps != gen->nr_maps) { 375 + pr_warn("nr_progs %d/%d nr_maps %d/%d mismatch\n", 376 + nr_progs, gen->nr_progs, nr_maps, gen->nr_maps); 376 377 gen->error = -EFAULT; 377 378 return gen->error; 378 379 } ··· 463 462 attr.map_flags = map_attr->map_flags; 464 463 attr.map_extra = map_attr->map_extra; 465 464 if (map_name) 466 - memcpy(attr.map_name, map_name, 467 - min((unsigned)strlen(map_name), BPF_OBJ_NAME_LEN - 1)); 465 + libbpf_strlcpy(attr.map_name, map_name, sizeof(attr.map_name)); 468 466 attr.numa_node = map_attr->numa_node; 469 467 attr.map_ifindex = map_attr->map_ifindex; 470 468 attr.max_entries = max_entries; ··· 969 969 core_relos = add_data(gen, gen->core_relos, 970 970 attr.core_relo_cnt * attr.core_relo_rec_size); 971 971 972 - memcpy(attr.prog_name, prog_name, 973 - min((unsigned)strlen(prog_name), BPF_OBJ_NAME_LEN - 1)); 972 + libbpf_strlcpy(attr.prog_name, prog_name, sizeof(attr.prog_name)); 974 973 prog_load_attr = add_data(gen, &attr, attr_size); 975 974 976 975 /* populate union bpf_attr with a pointer to license */
+41 -44
tools/lib/bpf/libbpf.c
··· 187 187 #undef __S 188 188 } 189 189 190 - enum kern_feature_id { 191 - /* v4.14: kernel support for program & map names. */ 192 - FEAT_PROG_NAME, 193 - /* v5.2: kernel support for global data sections. */ 194 - FEAT_GLOBAL_DATA, 195 - /* BTF support */ 196 - FEAT_BTF, 197 - /* BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO support */ 198 - FEAT_BTF_FUNC, 199 - /* BTF_KIND_VAR and BTF_KIND_DATASEC support */ 200 - FEAT_BTF_DATASEC, 201 - /* BTF_FUNC_GLOBAL is supported */ 202 - FEAT_BTF_GLOBAL_FUNC, 203 - /* BPF_F_MMAPABLE is supported for arrays */ 204 - FEAT_ARRAY_MMAP, 205 - /* kernel support for expected_attach_type in BPF_PROG_LOAD */ 206 - FEAT_EXP_ATTACH_TYPE, 207 - /* bpf_probe_read_{kernel,user}[_str] helpers */ 208 - FEAT_PROBE_READ_KERN, 209 - /* BPF_PROG_BIND_MAP is supported */ 210 - FEAT_PROG_BIND_MAP, 211 - /* Kernel support for module BTFs */ 212 - FEAT_MODULE_BTF, 213 - /* BTF_KIND_FLOAT support */ 214 - FEAT_BTF_FLOAT, 215 - /* BPF perf link support */ 216 - FEAT_PERF_LINK, 217 - /* BTF_KIND_DECL_TAG support */ 218 - FEAT_BTF_DECL_TAG, 219 - /* BTF_KIND_TYPE_TAG support */ 220 - FEAT_BTF_TYPE_TAG, 221 - __FEAT_CNT, 222 - }; 223 - 224 - static bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id); 225 - 226 190 enum reloc_type { 227 191 RELO_LD64, 228 192 RELO_CALL, ··· 795 831 return 0; 796 832 } 797 833 798 - static __u32 get_kernel_version(void) 834 + __u32 get_kernel_version(void) 799 835 { 836 + /* On Ubuntu LINUX_VERSION_CODE doesn't correspond to info.release, 837 + * but Ubuntu provides /proc/version_signature file, as described at 838 + * https://ubuntu.com/kernel, with an example contents below, which we 839 + * can use to get a proper LINUX_VERSION_CODE. 840 + * 841 + * Ubuntu 5.4.0-12.15-generic 5.4.8 842 + * 843 + * In the above, 5.4.8 is what kernel is actually expecting, while 844 + * uname() call will return 5.4.0 in info.release. 845 + */ 846 + const char *ubuntu_kver_file = "/proc/version_signature"; 800 847 __u32 major, minor, patch; 801 848 struct utsname info; 849 + 850 + if (access(ubuntu_kver_file, R_OK) == 0) { 851 + FILE *f; 852 + 853 + f = fopen(ubuntu_kver_file, "r"); 854 + if (f) { 855 + if (fscanf(f, "%*s %*s %d.%d.%d\n", &major, &minor, &patch) == 3) { 856 + fclose(f); 857 + return KERNEL_VERSION(major, minor, patch); 858 + } 859 + fclose(f); 860 + } 861 + /* something went wrong, fall back to uname() approach */ 862 + } 802 863 803 864 uname(&info); 804 865 if (sscanf(info.release, "%u.%u.%u", &major, &minor, &patch) != 3) ··· 1190 1201 1191 1202 strcpy(obj->path, path); 1192 1203 if (obj_name) { 1193 - strncpy(obj->name, obj_name, sizeof(obj->name) - 1); 1194 - obj->name[sizeof(obj->name) - 1] = 0; 1204 + libbpf_strlcpy(obj->name, obj_name, sizeof(obj->name)); 1195 1205 } else { 1196 1206 /* Using basename() GNU version which doesn't modify arg. */ 1197 - strncpy(obj->name, basename((void *)path), 1198 - sizeof(obj->name) - 1); 1207 + libbpf_strlcpy(obj->name, basename((void *)path), sizeof(obj->name)); 1199 1208 end = strchr(obj->name, '.'); 1200 1209 if (end) 1201 1210 *end = 0; ··· 1345 1358 static int 1346 1359 bpf_object__init_license(struct bpf_object *obj, void *data, size_t size) 1347 1360 { 1348 - memcpy(obj->license, data, min(size, sizeof(obj->license) - 1)); 1361 + /* libbpf_strlcpy() only copies first N - 1 bytes, so size + 1 won't 1362 + * go over allowed ELF data section buffer 1363 + */ 1364 + libbpf_strlcpy(obj->license, data, min(size + 1, sizeof(obj->license))); 1349 1365 pr_debug("license of %s is %s\n", obj->path, obj->license); 1350 1366 return 0; 1351 1367 } ··· 4344 4354 if (obj->gen_loader) 4345 4355 return 0; 4346 4356 4357 + ret = bump_rlimit_memlock(); 4358 + if (ret) 4359 + pr_warn("Failed to bump RLIMIT_MEMLOCK (err = %d), you might need to do it explicitly!\n", ret); 4360 + 4347 4361 /* make sure basic loading works */ 4348 4362 ret = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", insns, insn_cnt, NULL); 4349 4363 if (ret < 0) ··· 4714 4720 [FEAT_BTF_TYPE_TAG] = { 4715 4721 "BTF_KIND_TYPE_TAG support", probe_kern_btf_type_tag, 4716 4722 }, 4723 + [FEAT_MEMCG_ACCOUNT] = { 4724 + "memcg-based memory accounting", probe_memcg_account, 4725 + }, 4717 4726 }; 4718 4727 4719 - static bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id) 4728 + bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id) 4720 4729 { 4721 4730 struct kern_feature_desc *feat = &feature_probes[feat_id]; 4722 4731 int ret; 4723 4732 4724 - if (obj->gen_loader) 4733 + if (obj && obj->gen_loader) 4725 4734 /* To generate loader program assume the latest kernel 4726 4735 * to avoid doing extra prog_load, map_create syscalls. 4727 4736 */
+73 -4
tools/lib/bpf/libbpf.h
··· 227 227 LIBBPF_API struct btf *bpf_object__btf(const struct bpf_object *obj); 228 228 LIBBPF_API int bpf_object__btf_fd(const struct bpf_object *obj); 229 229 230 + LIBBPF_DEPRECATED_SINCE(0, 7, "use bpf_object__find_program_by_name() instead") 230 231 LIBBPF_API struct bpf_program * 231 232 bpf_object__find_program_by_title(const struct bpf_object *obj, 232 233 const char *title); ··· 340 339 LIBBPF_API int bpf_program__unpin_instance(struct bpf_program *prog, 341 340 const char *path, 342 341 int instance); 342 + 343 + /** 344 + * @brief **bpf_program__pin()** pins the BPF program to a file 345 + * in the BPF FS specified by a path. This increments the programs 346 + * reference count, allowing it to stay loaded after the process 347 + * which loaded it has exited. 348 + * 349 + * @param prog BPF program to pin, must already be loaded 350 + * @param path file path in a BPF file system 351 + * @return 0, on success; negative error code, otherwise 352 + */ 343 353 LIBBPF_API int bpf_program__pin(struct bpf_program *prog, const char *path); 354 + 355 + /** 356 + * @brief **bpf_program__unpin()** unpins the BPF program from a file 357 + * in the BPFFS specified by a path. This decrements the programs 358 + * reference count. 359 + * 360 + * The file pinning the BPF program can also be unlinked by a different 361 + * process in which case this function will return an error. 362 + * 363 + * @param prog BPF program to unpin 364 + * @param path file path to the pin in a BPF file system 365 + * @return 0, on success; negative error code, otherwise 366 + */ 344 367 LIBBPF_API int bpf_program__unpin(struct bpf_program *prog, const char *path); 345 368 LIBBPF_API void bpf_program__unload(struct bpf_program *prog); 346 369 ··· 1052 1027 * user, causing subsequent probes to fail. In this case, the caller may want 1053 1028 * to adjust that limit with setrlimit(). 1054 1029 */ 1055 - LIBBPF_API bool bpf_probe_prog_type(enum bpf_prog_type prog_type, 1056 - __u32 ifindex); 1030 + LIBBPF_DEPRECATED_SINCE(0, 8, "use libbpf_probe_bpf_prog_type() instead") 1031 + LIBBPF_API bool bpf_probe_prog_type(enum bpf_prog_type prog_type, __u32 ifindex); 1032 + LIBBPF_DEPRECATED_SINCE(0, 8, "use libbpf_probe_bpf_map_type() instead") 1057 1033 LIBBPF_API bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex); 1058 - LIBBPF_API bool bpf_probe_helper(enum bpf_func_id id, 1059 - enum bpf_prog_type prog_type, __u32 ifindex); 1034 + LIBBPF_DEPRECATED_SINCE(0, 8, "use libbpf_probe_bpf_helper() instead") 1035 + LIBBPF_API bool bpf_probe_helper(enum bpf_func_id id, enum bpf_prog_type prog_type, __u32 ifindex); 1036 + LIBBPF_DEPRECATED_SINCE(0, 8, "implement your own or use bpftool for feature detection") 1060 1037 LIBBPF_API bool bpf_probe_large_insn_limit(__u32 ifindex); 1038 + 1039 + /** 1040 + * @brief **libbpf_probe_bpf_prog_type()** detects if host kernel supports 1041 + * BPF programs of a given type. 1042 + * @param prog_type BPF program type to detect kernel support for 1043 + * @param opts reserved for future extensibility, should be NULL 1044 + * @return 1, if given program type is supported; 0, if given program type is 1045 + * not supported; negative error code if feature detection failed or can't be 1046 + * performed 1047 + * 1048 + * Make sure the process has required set of CAP_* permissions (or runs as 1049 + * root) when performing feature checking. 1050 + */ 1051 + LIBBPF_API int libbpf_probe_bpf_prog_type(enum bpf_prog_type prog_type, const void *opts); 1052 + /** 1053 + * @brief **libbpf_probe_bpf_map_type()** detects if host kernel supports 1054 + * BPF maps of a given type. 1055 + * @param map_type BPF map type to detect kernel support for 1056 + * @param opts reserved for future extensibility, should be NULL 1057 + * @return 1, if given map type is supported; 0, if given map type is 1058 + * not supported; negative error code if feature detection failed or can't be 1059 + * performed 1060 + * 1061 + * Make sure the process has required set of CAP_* permissions (or runs as 1062 + * root) when performing feature checking. 1063 + */ 1064 + LIBBPF_API int libbpf_probe_bpf_map_type(enum bpf_map_type map_type, const void *opts); 1065 + /** 1066 + * @brief **libbpf_probe_bpf_helper()** detects if host kernel supports the 1067 + * use of a given BPF helper from specified BPF program type. 1068 + * @param prog_type BPF program type used to check the support of BPF helper 1069 + * @param helper_id BPF helper ID (enum bpf_func_id) to check support for 1070 + * @param opts reserved for future extensibility, should be NULL 1071 + * @return 1, if given combination of program type and helper is supported; 0, 1072 + * if the combination is not supported; negative error code if feature 1073 + * detection for provided input arguments failed or can't be performed 1074 + * 1075 + * Make sure the process has required set of CAP_* permissions (or runs as 1076 + * root) when performing feature checking. 1077 + */ 1078 + LIBBPF_API int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, 1079 + enum bpf_func_id helper_id, const void *opts); 1061 1080 1062 1081 /* 1063 1082 * Get bpf_prog_info in continuous memory
+4
tools/lib/bpf/libbpf.map
··· 427 427 bpf_program__log_level; 428 428 bpf_program__set_log_buf; 429 429 bpf_program__set_log_level; 430 + libbpf_probe_bpf_helper; 431 + libbpf_probe_bpf_map_type; 432 + libbpf_probe_bpf_prog_type; 433 + libbpf_set_memlock_rlim_max; 430 434 };
+60
tools/lib/bpf/libbpf_internal.h
··· 169 169 return realloc(ptr, total); 170 170 } 171 171 172 + /* Copy up to sz - 1 bytes from zero-terminated src string and ensure that dst 173 + * is zero-terminated string no matter what (unless sz == 0, in which case 174 + * it's a no-op). It's conceptually close to FreeBSD's strlcpy(), but differs 175 + * in what is returned. Given this is internal helper, it's trivial to extend 176 + * this, when necessary. Use this instead of strncpy inside libbpf source code. 177 + */ 178 + static inline void libbpf_strlcpy(char *dst, const char *src, size_t sz) 179 + { 180 + size_t i; 181 + 182 + if (sz == 0) 183 + return; 184 + 185 + sz--; 186 + for (i = 0; i < sz && src[i]; i++) 187 + dst[i] = src[i]; 188 + dst[i] = '\0'; 189 + } 190 + 191 + __u32 get_kernel_version(void); 192 + 172 193 struct btf; 173 194 struct btf_type; 174 195 ··· 293 272 (opts)->sz - __off); \ 294 273 }) 295 274 275 + enum kern_feature_id { 276 + /* v4.14: kernel support for program & map names. */ 277 + FEAT_PROG_NAME, 278 + /* v5.2: kernel support for global data sections. */ 279 + FEAT_GLOBAL_DATA, 280 + /* BTF support */ 281 + FEAT_BTF, 282 + /* BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO support */ 283 + FEAT_BTF_FUNC, 284 + /* BTF_KIND_VAR and BTF_KIND_DATASEC support */ 285 + FEAT_BTF_DATASEC, 286 + /* BTF_FUNC_GLOBAL is supported */ 287 + FEAT_BTF_GLOBAL_FUNC, 288 + /* BPF_F_MMAPABLE is supported for arrays */ 289 + FEAT_ARRAY_MMAP, 290 + /* kernel support for expected_attach_type in BPF_PROG_LOAD */ 291 + FEAT_EXP_ATTACH_TYPE, 292 + /* bpf_probe_read_{kernel,user}[_str] helpers */ 293 + FEAT_PROBE_READ_KERN, 294 + /* BPF_PROG_BIND_MAP is supported */ 295 + FEAT_PROG_BIND_MAP, 296 + /* Kernel support for module BTFs */ 297 + FEAT_MODULE_BTF, 298 + /* BTF_KIND_FLOAT support */ 299 + FEAT_BTF_FLOAT, 300 + /* BPF perf link support */ 301 + FEAT_PERF_LINK, 302 + /* BTF_KIND_DECL_TAG support */ 303 + FEAT_BTF_DECL_TAG, 304 + /* BTF_KIND_TYPE_TAG support */ 305 + FEAT_BTF_TYPE_TAG, 306 + /* memcg-based accounting for BPF maps and progs */ 307 + FEAT_MEMCG_ACCOUNT, 308 + __FEAT_CNT, 309 + }; 310 + 311 + int probe_memcg_account(void); 312 + bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id); 313 + int bump_rlimit_memlock(void); 296 314 297 315 int parse_cpu_mask_str(const char *s, bool **mask, int *mask_sz); 298 316 int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz);
+11 -1
tools/lib/bpf/libbpf_legacy.h
··· 45 45 * (positive) error code. 46 46 */ 47 47 LIBBPF_STRICT_DIRECT_ERRS = 0x02, 48 - 49 48 /* 50 49 * Enforce strict BPF program section (SEC()) names. 51 50 * E.g., while prefiously SEC("xdp_whatever") or SEC("perf_event_blah") were ··· 62 63 * Clients can maintain it on their own if it is valuable for them. 63 64 */ 64 65 LIBBPF_STRICT_NO_OBJECT_LIST = 0x08, 66 + /* 67 + * Automatically bump RLIMIT_MEMLOCK using setrlimit() before the 68 + * first BPF program or map creation operation. This is done only if 69 + * kernel is too old to support memcg-based memory accounting for BPF 70 + * subsystem. By default, RLIMIT_MEMLOCK limit is set to RLIM_INFINITY, 71 + * but it can be overriden with libbpf_set_memlock_rlim_max() API. 72 + * Note that libbpf_set_memlock_rlim_max() needs to be called before 73 + * the very first bpf_prog_load(), bpf_map_create() or bpf_object__load() 74 + * operation. 75 + */ 76 + LIBBPF_STRICT_AUTO_RLIMIT_MEMLOCK = 0x10, 65 77 66 78 __LIBBPF_STRICT_LAST, 67 79 };
+186 -67
tools/lib/bpf/libbpf_probes.c
··· 48 48 return strtol(buf, NULL, 0); 49 49 } 50 50 51 - static int get_kernel_version(void) 51 + static int probe_prog_load(enum bpf_prog_type prog_type, 52 + const struct bpf_insn *insns, size_t insns_cnt, 53 + char *log_buf, size_t log_buf_sz, 54 + __u32 ifindex) 52 55 { 53 - int version, subversion, patchlevel; 54 - struct utsname utsn; 55 - 56 - /* Return 0 on failure, and attempt to probe with empty kversion */ 57 - if (uname(&utsn)) 58 - return 0; 59 - 60 - if (sscanf(utsn.release, "%d.%d.%d", 61 - &version, &subversion, &patchlevel) != 3) 62 - return 0; 63 - 64 - return (version << 16) + (subversion << 8) + patchlevel; 65 - } 66 - 67 - static void 68 - probe_load(enum bpf_prog_type prog_type, const struct bpf_insn *insns, 69 - size_t insns_cnt, char *buf, size_t buf_len, __u32 ifindex) 70 - { 71 - LIBBPF_OPTS(bpf_prog_load_opts, opts); 72 - int fd; 56 + LIBBPF_OPTS(bpf_prog_load_opts, opts, 57 + .log_buf = log_buf, 58 + .log_size = log_buf_sz, 59 + .log_level = log_buf ? 1 : 0, 60 + .prog_ifindex = ifindex, 61 + ); 62 + int fd, err, exp_err = 0; 63 + const char *exp_msg = NULL; 64 + char buf[4096]; 73 65 74 66 switch (prog_type) { 75 67 case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: ··· 75 83 break; 76 84 case BPF_PROG_TYPE_KPROBE: 77 85 opts.kern_version = get_kernel_version(); 86 + break; 87 + case BPF_PROG_TYPE_LIRC_MODE2: 88 + opts.expected_attach_type = BPF_LIRC_MODE2; 89 + break; 90 + case BPF_PROG_TYPE_TRACING: 91 + case BPF_PROG_TYPE_LSM: 92 + opts.log_buf = buf; 93 + opts.log_size = sizeof(buf); 94 + opts.log_level = 1; 95 + if (prog_type == BPF_PROG_TYPE_TRACING) 96 + opts.expected_attach_type = BPF_TRACE_FENTRY; 97 + else 98 + opts.expected_attach_type = BPF_MODIFY_RETURN; 99 + opts.attach_btf_id = 1; 100 + 101 + exp_err = -EINVAL; 102 + exp_msg = "attach_btf_id 1 is not a function"; 103 + break; 104 + case BPF_PROG_TYPE_EXT: 105 + opts.log_buf = buf; 106 + opts.log_size = sizeof(buf); 107 + opts.log_level = 1; 108 + opts.attach_btf_id = 1; 109 + 110 + exp_err = -EINVAL; 111 + exp_msg = "Cannot replace kernel functions"; 112 + break; 113 + case BPF_PROG_TYPE_SYSCALL: 114 + opts.prog_flags = BPF_F_SLEEPABLE; 115 + break; 116 + case BPF_PROG_TYPE_STRUCT_OPS: 117 + exp_err = -524; /* -ENOTSUPP */ 78 118 break; 79 119 case BPF_PROG_TYPE_UNSPEC: 80 120 case BPF_PROG_TYPE_SOCKET_FILTER: ··· 127 103 case BPF_PROG_TYPE_RAW_TRACEPOINT: 128 104 case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE: 129 105 case BPF_PROG_TYPE_LWT_SEG6LOCAL: 130 - case BPF_PROG_TYPE_LIRC_MODE2: 131 106 case BPF_PROG_TYPE_SK_REUSEPORT: 132 107 case BPF_PROG_TYPE_FLOW_DISSECTOR: 133 108 case BPF_PROG_TYPE_CGROUP_SYSCTL: 134 - case BPF_PROG_TYPE_TRACING: 135 - case BPF_PROG_TYPE_STRUCT_OPS: 136 - case BPF_PROG_TYPE_EXT: 137 - case BPF_PROG_TYPE_LSM: 138 - default: 139 109 break; 110 + default: 111 + return -EOPNOTSUPP; 140 112 } 141 113 142 - opts.prog_ifindex = ifindex; 143 - opts.log_buf = buf; 144 - opts.log_size = buf_len; 145 - 146 - fd = bpf_prog_load(prog_type, NULL, "GPL", insns, insns_cnt, NULL); 114 + fd = bpf_prog_load(prog_type, NULL, "GPL", insns, insns_cnt, &opts); 115 + err = -errno; 147 116 if (fd >= 0) 148 117 close(fd); 118 + if (exp_err) { 119 + if (fd >= 0 || err != exp_err) 120 + return 0; 121 + if (exp_msg && !strstr(buf, exp_msg)) 122 + return 0; 123 + return 1; 124 + } 125 + return fd >= 0 ? 1 : 0; 126 + } 127 + 128 + int libbpf_probe_bpf_prog_type(enum bpf_prog_type prog_type, const void *opts) 129 + { 130 + struct bpf_insn insns[] = { 131 + BPF_MOV64_IMM(BPF_REG_0, 0), 132 + BPF_EXIT_INSN() 133 + }; 134 + const size_t insn_cnt = ARRAY_SIZE(insns); 135 + int ret; 136 + 137 + if (opts) 138 + return libbpf_err(-EINVAL); 139 + 140 + ret = probe_prog_load(prog_type, insns, insn_cnt, NULL, 0, 0); 141 + return libbpf_err(ret); 149 142 } 150 143 151 144 bool bpf_probe_prog_type(enum bpf_prog_type prog_type, __u32 ifindex) ··· 172 131 BPF_EXIT_INSN() 173 132 }; 174 133 134 + /* prefer libbpf_probe_bpf_prog_type() unless offload is requested */ 135 + if (ifindex == 0) 136 + return libbpf_probe_bpf_prog_type(prog_type, NULL) == 1; 137 + 175 138 if (ifindex && prog_type == BPF_PROG_TYPE_SCHED_CLS) 176 139 /* nfp returns -EINVAL on exit(0) with TC offload */ 177 140 insns[0].imm = 2; 178 141 179 142 errno = 0; 180 - probe_load(prog_type, insns, ARRAY_SIZE(insns), NULL, 0, ifindex); 143 + probe_prog_load(prog_type, insns, ARRAY_SIZE(insns), NULL, 0, ifindex); 181 144 182 145 return errno != EINVAL && errno != EOPNOTSUPP; 183 146 } ··· 242 197 strs, sizeof(strs)); 243 198 } 244 199 245 - bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex) 200 + static int probe_map_create(enum bpf_map_type map_type, __u32 ifindex) 246 201 { 247 - int key_size, value_size, max_entries, map_flags; 202 + LIBBPF_OPTS(bpf_map_create_opts, opts); 203 + int key_size, value_size, max_entries; 248 204 __u32 btf_key_type_id = 0, btf_value_type_id = 0; 249 - int fd = -1, btf_fd = -1, fd_inner; 205 + int fd = -1, btf_fd = -1, fd_inner = -1, exp_err = 0, err; 206 + 207 + opts.map_ifindex = ifindex; 250 208 251 209 key_size = sizeof(__u32); 252 210 value_size = sizeof(__u32); 253 211 max_entries = 1; 254 - map_flags = 0; 255 212 256 213 switch (map_type) { 257 214 case BPF_MAP_TYPE_STACK_TRACE: ··· 262 215 case BPF_MAP_TYPE_LPM_TRIE: 263 216 key_size = sizeof(__u64); 264 217 value_size = sizeof(__u64); 265 - map_flags = BPF_F_NO_PREALLOC; 218 + opts.map_flags = BPF_F_NO_PREALLOC; 266 219 break; 267 220 case BPF_MAP_TYPE_CGROUP_STORAGE: 268 221 case BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE: ··· 281 234 btf_value_type_id = 3; 282 235 value_size = 8; 283 236 max_entries = 0; 284 - map_flags = BPF_F_NO_PREALLOC; 237 + opts.map_flags = BPF_F_NO_PREALLOC; 285 238 btf_fd = load_local_storage_btf(); 286 239 if (btf_fd < 0) 287 - return false; 240 + return btf_fd; 288 241 break; 289 242 case BPF_MAP_TYPE_RINGBUF: 290 243 key_size = 0; 291 244 value_size = 0; 292 245 max_entries = 4096; 293 246 break; 294 - case BPF_MAP_TYPE_UNSPEC: 247 + case BPF_MAP_TYPE_STRUCT_OPS: 248 + /* we'll get -ENOTSUPP for invalid BTF type ID for struct_ops */ 249 + opts.btf_vmlinux_value_type_id = 1; 250 + exp_err = -524; /* -ENOTSUPP */ 251 + break; 252 + case BPF_MAP_TYPE_BLOOM_FILTER: 253 + key_size = 0; 254 + max_entries = 1; 255 + break; 295 256 case BPF_MAP_TYPE_HASH: 296 257 case BPF_MAP_TYPE_ARRAY: 297 258 case BPF_MAP_TYPE_PROG_ARRAY: ··· 318 263 case BPF_MAP_TYPE_XSKMAP: 319 264 case BPF_MAP_TYPE_SOCKHASH: 320 265 case BPF_MAP_TYPE_REUSEPORT_SOCKARRAY: 321 - case BPF_MAP_TYPE_STRUCT_OPS: 322 - default: 323 266 break; 267 + case BPF_MAP_TYPE_UNSPEC: 268 + default: 269 + return -EOPNOTSUPP; 324 270 } 325 271 326 272 if (map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS || 327 273 map_type == BPF_MAP_TYPE_HASH_OF_MAPS) { 328 - LIBBPF_OPTS(bpf_map_create_opts, opts); 329 - 330 274 /* TODO: probe for device, once libbpf has a function to create 331 275 * map-in-map for offload 332 276 */ 333 277 if (ifindex) 334 - return false; 278 + goto cleanup; 335 279 336 280 fd_inner = bpf_map_create(BPF_MAP_TYPE_HASH, NULL, 337 281 sizeof(__u32), sizeof(__u32), 1, NULL); 338 282 if (fd_inner < 0) 339 - return false; 283 + goto cleanup; 340 284 341 285 opts.inner_map_fd = fd_inner; 342 - fd = bpf_map_create(map_type, NULL, sizeof(__u32), sizeof(__u32), 1, &opts); 343 - close(fd_inner); 344 - } else { 345 - LIBBPF_OPTS(bpf_map_create_opts, opts); 346 - 347 - /* Note: No other restriction on map type probes for offload */ 348 - opts.map_flags = map_flags; 349 - opts.map_ifindex = ifindex; 350 - if (btf_fd >= 0) { 351 - opts.btf_fd = btf_fd; 352 - opts.btf_key_type_id = btf_key_type_id; 353 - opts.btf_value_type_id = btf_value_type_id; 354 - } 355 - 356 - fd = bpf_map_create(map_type, NULL, key_size, value_size, max_entries, &opts); 357 286 } 287 + 288 + if (btf_fd >= 0) { 289 + opts.btf_fd = btf_fd; 290 + opts.btf_key_type_id = btf_key_type_id; 291 + opts.btf_value_type_id = btf_value_type_id; 292 + } 293 + 294 + fd = bpf_map_create(map_type, NULL, key_size, value_size, max_entries, &opts); 295 + err = -errno; 296 + 297 + cleanup: 358 298 if (fd >= 0) 359 299 close(fd); 300 + if (fd_inner >= 0) 301 + close(fd_inner); 360 302 if (btf_fd >= 0) 361 303 close(btf_fd); 362 304 363 - return fd >= 0; 305 + if (exp_err) 306 + return fd < 0 && err == exp_err ? 1 : 0; 307 + else 308 + return fd >= 0 ? 1 : 0; 309 + } 310 + 311 + int libbpf_probe_bpf_map_type(enum bpf_map_type map_type, const void *opts) 312 + { 313 + int ret; 314 + 315 + if (opts) 316 + return libbpf_err(-EINVAL); 317 + 318 + ret = probe_map_create(map_type, 0); 319 + return libbpf_err(ret); 320 + } 321 + 322 + bool bpf_probe_map_type(enum bpf_map_type map_type, __u32 ifindex) 323 + { 324 + return probe_map_create(map_type, ifindex) == 1; 325 + } 326 + 327 + int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helper_id, 328 + const void *opts) 329 + { 330 + struct bpf_insn insns[] = { 331 + BPF_EMIT_CALL((__u32)helper_id), 332 + BPF_EXIT_INSN(), 333 + }; 334 + const size_t insn_cnt = ARRAY_SIZE(insns); 335 + char buf[4096]; 336 + int ret; 337 + 338 + if (opts) 339 + return libbpf_err(-EINVAL); 340 + 341 + /* we can't successfully load all prog types to check for BPF helper 342 + * support, so bail out with -EOPNOTSUPP error 343 + */ 344 + switch (prog_type) { 345 + case BPF_PROG_TYPE_TRACING: 346 + case BPF_PROG_TYPE_EXT: 347 + case BPF_PROG_TYPE_LSM: 348 + case BPF_PROG_TYPE_STRUCT_OPS: 349 + return -EOPNOTSUPP; 350 + default: 351 + break; 352 + } 353 + 354 + buf[0] = '\0'; 355 + ret = probe_prog_load(prog_type, insns, insn_cnt, buf, sizeof(buf), 0); 356 + if (ret < 0) 357 + return libbpf_err(ret); 358 + 359 + /* If BPF verifier doesn't recognize BPF helper ID (enum bpf_func_id) 360 + * at all, it will emit something like "invalid func unknown#181". 361 + * If BPF verifier recognizes BPF helper but it's not supported for 362 + * given BPF program type, it will emit "unknown func bpf_sys_bpf#166". 363 + * In both cases, provided combination of BPF program type and BPF 364 + * helper is not supported by the kernel. 365 + * In all other cases, probe_prog_load() above will either succeed (e.g., 366 + * because BPF helper happens to accept no input arguments or it 367 + * accepts one input argument and initial PTR_TO_CTX is fine for 368 + * that), or we'll get some more specific BPF verifier error about 369 + * some unsatisfied conditions. 370 + */ 371 + if (ret == 0 && (strstr(buf, "invalid func ") || strstr(buf, "unknown func "))) 372 + return 0; 373 + return 1; /* assume supported */ 364 374 } 365 375 366 376 bool bpf_probe_helper(enum bpf_func_id id, enum bpf_prog_type prog_type, ··· 438 318 char buf[4096] = {}; 439 319 bool res; 440 320 441 - probe_load(prog_type, insns, ARRAY_SIZE(insns), buf, sizeof(buf), 442 - ifindex); 321 + probe_prog_load(prog_type, insns, ARRAY_SIZE(insns), buf, sizeof(buf), ifindex); 443 322 res = !grep(buf, "invalid func ") && !grep(buf, "unknown func "); 444 323 445 324 if (ifindex) { ··· 470 351 insns[BPF_MAXINSNS] = BPF_EXIT_INSN(); 471 352 472 353 errno = 0; 473 - probe_load(BPF_PROG_TYPE_SCHED_CLS, insns, ARRAY_SIZE(insns), NULL, 0, 474 - ifindex); 354 + probe_prog_load(BPF_PROG_TYPE_SCHED_CLS, insns, ARRAY_SIZE(insns), NULL, 0, 355 + ifindex); 475 356 476 357 return errno != E2BIG && errno != EINVAL; 477 358 }
+15 -5
tools/lib/bpf/relo_core.c
··· 709 709 710 710 static int bpf_core_calc_type_relo(const struct bpf_core_relo *relo, 711 711 const struct bpf_core_spec *spec, 712 - __u32 *val) 712 + __u32 *val, bool *validate) 713 713 { 714 714 __s64 sz; 715 + 716 + /* by default, always check expected value in bpf_insn */ 717 + if (validate) 718 + *validate = true; 715 719 716 720 /* type-based relos return zero when target type is not found */ 717 721 if (!spec) { ··· 726 722 switch (relo->kind) { 727 723 case BPF_CORE_TYPE_ID_TARGET: 728 724 *val = spec->root_type_id; 725 + /* type ID, embedded in bpf_insn, might change during linking, 726 + * so enforcing it is pointless 727 + */ 728 + if (validate) 729 + *validate = false; 729 730 break; 730 731 case BPF_CORE_TYPE_EXISTS: 731 732 *val = 1; ··· 870 861 res->fail_memsz_adjust = true; 871 862 } 872 863 } else if (core_relo_is_type_based(relo->kind)) { 873 - err = bpf_core_calc_type_relo(relo, local_spec, &res->orig_val); 874 - err = err ?: bpf_core_calc_type_relo(relo, targ_spec, &res->new_val); 864 + err = bpf_core_calc_type_relo(relo, local_spec, &res->orig_val, &res->validate); 865 + err = err ?: bpf_core_calc_type_relo(relo, targ_spec, &res->new_val, NULL); 875 866 } else if (core_relo_is_enumval_based(relo->kind)) { 876 867 err = bpf_core_calc_enumval_relo(relo, local_spec, &res->orig_val); 877 868 err = err ?: bpf_core_calc_enumval_relo(relo, targ_spec, &res->new_val); ··· 1222 1213 1223 1214 /* TYPE_ID_LOCAL relo is special and doesn't need candidate search */ 1224 1215 if (relo->kind == BPF_CORE_TYPE_ID_LOCAL) { 1225 - targ_res.validate = true; 1216 + /* bpf_insn's imm value could get out of sync during linking */ 1217 + memset(&targ_res, 0, sizeof(targ_res)); 1218 + targ_res.validate = false; 1226 1219 targ_res.poison = false; 1227 1220 targ_res.orig_val = local_spec->root_type_id; 1228 1221 targ_res.new_val = local_spec->root_type_id; ··· 1237 1226 prog_name, relo_idx, core_relo_kind_str(relo->kind), relo->kind); 1238 1227 return -EOPNOTSUPP; 1239 1228 } 1240 - 1241 1229 1242 1230 for (i = 0, j = 0; i < cands->len; i++) { 1243 1231 err = bpf_core_spec_match(local_spec, cands->cands[i].btf,
+3 -6
tools/lib/bpf/xsk.c
··· 548 548 return -errno; 549 549 550 550 ifr.ifr_data = (void *)&channels; 551 - memcpy(ifr.ifr_name, ctx->ifname, IFNAMSIZ - 1); 552 - ifr.ifr_name[IFNAMSIZ - 1] = '\0'; 551 + libbpf_strlcpy(ifr.ifr_name, ctx->ifname, IFNAMSIZ); 553 552 err = ioctl(fd, SIOCETHTOOL, &ifr); 554 553 if (err && errno != EOPNOTSUPP) { 555 554 ret = -errno; ··· 767 768 } 768 769 769 770 ctx->ifindex = ifindex; 770 - memcpy(ctx->ifname, ifname, IFNAMSIZ -1); 771 - ctx->ifname[IFNAMSIZ - 1] = 0; 771 + libbpf_strlcpy(ctx->ifname, ifname, IFNAMSIZ); 772 772 773 773 xsk->ctx = ctx; 774 774 xsk->ctx->has_bpf_link = xsk_probe_bpf_link(); ··· 949 951 ctx->refcount = 1; 950 952 ctx->umem = umem; 951 953 ctx->queue_id = queue_id; 952 - memcpy(ctx->ifname, ifname, IFNAMSIZ - 1); 953 - ctx->ifname[IFNAMSIZ - 1] = '\0'; 954 + libbpf_strlcpy(ctx->ifname, ifname, IFNAMSIZ); 954 955 955 956 ctx->fill = fill; 956 957 ctx->comp = comp;
+12 -1
tools/perf/builtin-trace.c
··· 3257 3257 3258 3258 static struct bpf_program *trace__find_bpf_program_by_title(struct trace *trace, const char *name) 3259 3259 { 3260 + struct bpf_program *pos, *prog = NULL; 3261 + const char *sec_name; 3262 + 3260 3263 if (trace->bpf_obj == NULL) 3261 3264 return NULL; 3262 3265 3263 - return bpf_object__find_program_by_title(trace->bpf_obj, name); 3266 + bpf_object__for_each_program(pos, trace->bpf_obj) { 3267 + sec_name = bpf_program__section_name(pos); 3268 + if (sec_name && !strcmp(sec_name, name)) { 3269 + prog = pos; 3270 + break; 3271 + } 3272 + } 3273 + 3274 + return prog; 3264 3275 } 3265 3276 3266 3277 static struct bpf_program *trace__find_syscall_bpf_prog(struct trace *trace, struct syscall *sc,
+12 -1
tools/scripts/Makefile.include
··· 87 87 88 88 ifeq ($(CC_NO_CLANG), 1) 89 89 EXTRA_WARNINGS += -Wstrict-aliasing=3 90 - endif 90 + 91 + else ifneq ($(CROSS_COMPILE),) 92 + CLANG_CROSS_FLAGS := --target=$(notdir $(CROSS_COMPILE:%-=%)) 93 + GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE)gcc)) 94 + ifneq ($(GCC_TOOLCHAIN_DIR),) 95 + CLANG_CROSS_FLAGS += --prefix=$(GCC_TOOLCHAIN_DIR)$(notdir $(CROSS_COMPILE)) 96 + CLANG_CROSS_FLAGS += --sysroot=$(shell $(CROSS_COMPILE)gcc -print-sysroot) 97 + CLANG_CROSS_FLAGS += --gcc-toolchain=$(realpath $(GCC_TOOLCHAIN_DIR)/..) 98 + endif # GCC_TOOLCHAIN_DIR 99 + CFLAGS += $(CLANG_CROSS_FLAGS) 100 + AFLAGS += $(CLANG_CROSS_FLAGS) 101 + endif # CROSS_COMPILE 91 102 92 103 # Hack to avoid type-punned warnings on old systems such as RHEL5: 93 104 # We should be changing CFLAGS and checking gcc version, but this
+7 -5
tools/testing/selftests/bpf/Makefile
··· 170 170 171 171 $(OUTPUT)/urandom_read: urandom_read.c 172 172 $(call msg,BINARY,,$@) 173 - $(Q)$(CC) $(LDFLAGS) $< $(LDLIBS) -Wl,--build-id=sha1 -o $@ 173 + $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $< $(LDLIBS) -Wl,--build-id=sha1 -o $@ 174 174 175 175 $(OUTPUT)/bpf_testmod.ko: $(VMLINUX_BTF) $(wildcard bpf_testmod/Makefile bpf_testmod/*.[ch]) 176 176 $(call msg,MOD,,$@) ··· 217 217 $(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \ 218 218 $(HOST_BPFOBJ) | $(HOST_BUILD_DIR)/bpftool 219 219 $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOLDIR) \ 220 - CC=$(HOSTCC) LD=$(HOSTLD) \ 220 + ARCH= CROSS_COMPILE= CC=$(HOSTCC) LD=$(HOSTLD) \ 221 221 EXTRA_CFLAGS='-g -O0' \ 222 222 OUTPUT=$(HOST_BUILD_DIR)/bpftool/ \ 223 223 LIBBPF_OUTPUT=$(HOST_BUILD_DIR)/libbpf/ \ ··· 248 248 $(APIDIR)/linux/bpf.h \ 249 249 | $(HOST_BUILD_DIR)/libbpf 250 250 $(Q)$(MAKE) $(submake_extras) -C $(BPFDIR) \ 251 - EXTRA_CFLAGS='-g -O0' \ 251 + EXTRA_CFLAGS='-g -O0' ARCH= CROSS_COMPILE= \ 252 252 OUTPUT=$(HOST_BUILD_DIR)/libbpf/ CC=$(HOSTCC) LD=$(HOSTLD) \ 253 253 DESTDIR=$(HOST_SCRATCH_DIR)/ prefix= all install_headers 254 254 endif ··· 537 537 $(OUTPUT)/perfbuf_bench.skel.h 538 538 $(OUTPUT)/bench_bloom_filter_map.o: $(OUTPUT)/bloom_filter_bench.skel.h 539 539 $(OUTPUT)/bench_bpf_loop.o: $(OUTPUT)/bpf_loop_bench.skel.h 540 + $(OUTPUT)/bench_strncmp.o: $(OUTPUT)/strncmp_bench.skel.h 540 541 $(OUTPUT)/bench.o: bench.h testing_helpers.h $(BPFOBJ) 541 542 $(OUTPUT)/bench: LDLIBS += -lm 542 543 $(OUTPUT)/bench: $(OUTPUT)/bench.o \ ··· 548 547 $(OUTPUT)/bench_trigger.o \ 549 548 $(OUTPUT)/bench_ringbufs.o \ 550 549 $(OUTPUT)/bench_bloom_filter_map.o \ 551 - $(OUTPUT)/bench_bpf_loop.o 550 + $(OUTPUT)/bench_bpf_loop.o \ 551 + $(OUTPUT)/bench_strncmp.o 552 552 $(call msg,BINARY,,$@) 553 - $(Q)$(CC) $(LDFLAGS) $(filter %.a %.o,$^) $(LDLIBS) -o $@ 553 + $(Q)$(CC) $(CFLAGS) $(LDFLAGS) $(filter %.a %.o,$^) $(LDLIBS) -o $@ 554 554 555 555 EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(SCRATCH_DIR) $(HOST_SCRATCH_DIR) \ 556 556 prog_tests/tests.h map_tests/tests.h verifier/tests.h \
+7 -17
tools/testing/selftests/bpf/bench.c
··· 29 29 return vfprintf(stderr, format, args); 30 30 } 31 31 32 - static int bump_memlock_rlimit(void) 32 + void setup_libbpf(void) 33 33 { 34 - struct rlimit rlim_new = { 35 - .rlim_cur = RLIM_INFINITY, 36 - .rlim_max = RLIM_INFINITY, 37 - }; 38 - 39 - return setrlimit(RLIMIT_MEMLOCK, &rlim_new); 40 - } 41 - 42 - void setup_libbpf() 43 - { 44 - int err; 45 - 46 34 libbpf_set_strict_mode(LIBBPF_STRICT_ALL); 47 35 libbpf_set_print(libbpf_print_fn); 48 - 49 - err = bump_memlock_rlimit(); 50 - if (err) 51 - fprintf(stderr, "failed to increase RLIMIT_MEMLOCK: %d", err); 52 36 } 53 37 54 38 void false_hits_report_progress(int iter, struct bench_res *res, long delta_ns) ··· 189 205 extern struct argp bench_ringbufs_argp; 190 206 extern struct argp bench_bloom_map_argp; 191 207 extern struct argp bench_bpf_loop_argp; 208 + extern struct argp bench_strncmp_argp; 192 209 193 210 static const struct argp_child bench_parsers[] = { 194 211 { &bench_ringbufs_argp, 0, "Ring buffers benchmark", 0 }, 195 212 { &bench_bloom_map_argp, 0, "Bloom filter map benchmark", 0 }, 196 213 { &bench_bpf_loop_argp, 0, "bpf_loop helper benchmark", 0 }, 214 + { &bench_strncmp_argp, 0, "bpf_strncmp helper benchmark", 0 }, 197 215 {}, 198 216 }; 199 217 ··· 395 409 extern const struct bench bench_hashmap_without_bloom; 396 410 extern const struct bench bench_hashmap_with_bloom; 397 411 extern const struct bench bench_bpf_loop; 412 + extern const struct bench bench_strncmp_no_helper; 413 + extern const struct bench bench_strncmp_helper; 398 414 399 415 static const struct bench *benchs[] = { 400 416 &bench_count_global, ··· 429 441 &bench_hashmap_without_bloom, 430 442 &bench_hashmap_with_bloom, 431 443 &bench_bpf_loop, 444 + &bench_strncmp_no_helper, 445 + &bench_strncmp_helper, 432 446 }; 433 447 434 448 static void setup_benchmark()
+5 -4
tools/testing/selftests/bpf/bench.h
··· 38 38 39 39 struct bench { 40 40 const char *name; 41 - void (*validate)(); 42 - void (*setup)(); 41 + void (*validate)(void); 42 + void (*setup)(void); 43 43 void *(*producer_thread)(void *ctx); 44 44 void *(*consumer_thread)(void *ctx); 45 45 void (*measure)(struct bench_res* res); ··· 54 54 extern struct env env; 55 55 extern const struct bench *bench; 56 56 57 - void setup_libbpf(); 57 + void setup_libbpf(void); 58 58 void hits_drops_report_progress(int iter, struct bench_res *res, long delta_ns); 59 59 void hits_drops_report_final(struct bench_res res[], int res_cnt); 60 60 void false_hits_report_progress(int iter, struct bench_res *res, long delta_ns); ··· 62 62 void ops_report_progress(int iter, struct bench_res *res, long delta_ns); 63 63 void ops_report_final(struct bench_res res[], int res_cnt); 64 64 65 - static inline __u64 get_time_ns() { 65 + static inline __u64 get_time_ns(void) 66 + { 66 67 struct timespec t; 67 68 68 69 clock_gettime(CLOCK_MONOTONIC, &t);
+1 -1
tools/testing/selftests/bpf/benchs/bench_count.c
··· 36 36 struct counter *hits; 37 37 } count_local_ctx; 38 38 39 - static void count_local_setup() 39 + static void count_local_setup(void) 40 40 { 41 41 struct count_local_ctx *ctx = &count_local_ctx; 42 42
+8 -8
tools/testing/selftests/bpf/benchs/bench_rename.c
··· 11 11 int fd; 12 12 } ctx; 13 13 14 - static void validate() 14 + static void validate(void) 15 15 { 16 16 if (env.producer_cnt != 1) { 17 17 fprintf(stderr, "benchmark doesn't support multi-producer!\n"); ··· 43 43 res->hits = atomic_swap(&ctx.hits.value, 0); 44 44 } 45 45 46 - static void setup_ctx() 46 + static void setup_ctx(void) 47 47 { 48 48 setup_libbpf(); 49 49 ··· 71 71 } 72 72 } 73 73 74 - static void setup_base() 74 + static void setup_base(void) 75 75 { 76 76 setup_ctx(); 77 77 } 78 78 79 - static void setup_kprobe() 79 + static void setup_kprobe(void) 80 80 { 81 81 setup_ctx(); 82 82 attach_bpf(ctx.skel->progs.prog1); 83 83 } 84 84 85 - static void setup_kretprobe() 85 + static void setup_kretprobe(void) 86 86 { 87 87 setup_ctx(); 88 88 attach_bpf(ctx.skel->progs.prog2); 89 89 } 90 90 91 - static void setup_rawtp() 91 + static void setup_rawtp(void) 92 92 { 93 93 setup_ctx(); 94 94 attach_bpf(ctx.skel->progs.prog3); 95 95 } 96 96 97 - static void setup_fentry() 97 + static void setup_fentry(void) 98 98 { 99 99 setup_ctx(); 100 100 attach_bpf(ctx.skel->progs.prog4); 101 101 } 102 102 103 - static void setup_fexit() 103 + static void setup_fexit(void) 104 104 { 105 105 setup_ctx(); 106 106 attach_bpf(ctx.skel->progs.prog5);
+7 -7
tools/testing/selftests/bpf/benchs/bench_ringbufs.c
··· 88 88 89 89 static struct counter buf_hits; 90 90 91 - static inline void bufs_trigger_batch() 91 + static inline void bufs_trigger_batch(void) 92 92 { 93 93 (void)syscall(__NR_getpgid); 94 94 } 95 95 96 - static void bufs_validate() 96 + static void bufs_validate(void) 97 97 { 98 98 if (env.consumer_cnt != 1) { 99 99 fprintf(stderr, "rb-libbpf benchmark doesn't support multi-consumer!\n"); ··· 132 132 res->drops = atomic_swap(&ctx->skel->bss->dropped, 0); 133 133 } 134 134 135 - static struct ringbuf_bench *ringbuf_setup_skeleton() 135 + static struct ringbuf_bench *ringbuf_setup_skeleton(void) 136 136 { 137 137 struct ringbuf_bench *skel; 138 138 ··· 167 167 return 0; 168 168 } 169 169 170 - static void ringbuf_libbpf_setup() 170 + static void ringbuf_libbpf_setup(void) 171 171 { 172 172 struct ringbuf_libbpf_ctx *ctx = &ringbuf_libbpf_ctx; 173 173 struct bpf_link *link; ··· 223 223 res->drops = atomic_swap(&ctx->skel->bss->dropped, 0); 224 224 } 225 225 226 - static void ringbuf_custom_setup() 226 + static void ringbuf_custom_setup(void) 227 227 { 228 228 struct ringbuf_custom_ctx *ctx = &ringbuf_custom_ctx; 229 229 const size_t page_size = getpagesize(); ··· 352 352 res->drops = atomic_swap(&ctx->skel->bss->dropped, 0); 353 353 } 354 354 355 - static struct perfbuf_bench *perfbuf_setup_skeleton() 355 + static struct perfbuf_bench *perfbuf_setup_skeleton(void) 356 356 { 357 357 struct perfbuf_bench *skel; 358 358 ··· 390 390 return LIBBPF_PERF_EVENT_CONT; 391 391 } 392 392 393 - static void perfbuf_libbpf_setup() 393 + static void perfbuf_libbpf_setup(void) 394 394 { 395 395 struct perfbuf_libbpf_ctx *ctx = &perfbuf_libbpf_ctx; 396 396 struct perf_event_attr attr;
+161
tools/testing/selftests/bpf/benchs/bench_strncmp.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (C) 2021. Huawei Technologies Co., Ltd */ 3 + #include <argp.h> 4 + #include "bench.h" 5 + #include "strncmp_bench.skel.h" 6 + 7 + static struct strncmp_ctx { 8 + struct strncmp_bench *skel; 9 + } ctx; 10 + 11 + static struct strncmp_args { 12 + u32 cmp_str_len; 13 + } args = { 14 + .cmp_str_len = 32, 15 + }; 16 + 17 + enum { 18 + ARG_CMP_STR_LEN = 5000, 19 + }; 20 + 21 + static const struct argp_option opts[] = { 22 + { "cmp-str-len", ARG_CMP_STR_LEN, "CMP_STR_LEN", 0, 23 + "Set the length of compared string" }, 24 + {}, 25 + }; 26 + 27 + static error_t strncmp_parse_arg(int key, char *arg, struct argp_state *state) 28 + { 29 + switch (key) { 30 + case ARG_CMP_STR_LEN: 31 + args.cmp_str_len = strtoul(arg, NULL, 10); 32 + if (!args.cmp_str_len || 33 + args.cmp_str_len >= sizeof(ctx.skel->bss->str)) { 34 + fprintf(stderr, "Invalid cmp str len (limit %zu)\n", 35 + sizeof(ctx.skel->bss->str)); 36 + argp_usage(state); 37 + } 38 + break; 39 + default: 40 + return ARGP_ERR_UNKNOWN; 41 + } 42 + 43 + return 0; 44 + } 45 + 46 + const struct argp bench_strncmp_argp = { 47 + .options = opts, 48 + .parser = strncmp_parse_arg, 49 + }; 50 + 51 + static void strncmp_validate(void) 52 + { 53 + if (env.consumer_cnt != 1) { 54 + fprintf(stderr, "strncmp benchmark doesn't support multi-consumer!\n"); 55 + exit(1); 56 + } 57 + } 58 + 59 + static void strncmp_setup(void) 60 + { 61 + int err; 62 + char *target; 63 + size_t i, sz; 64 + 65 + sz = sizeof(ctx.skel->rodata->target); 66 + if (!sz || sz < sizeof(ctx.skel->bss->str)) { 67 + fprintf(stderr, "invalid string size (target %zu, src %zu)\n", 68 + sz, sizeof(ctx.skel->bss->str)); 69 + exit(1); 70 + } 71 + 72 + setup_libbpf(); 73 + 74 + ctx.skel = strncmp_bench__open(); 75 + if (!ctx.skel) { 76 + fprintf(stderr, "failed to open skeleton\n"); 77 + exit(1); 78 + } 79 + 80 + srandom(time(NULL)); 81 + target = ctx.skel->rodata->target; 82 + for (i = 0; i < sz - 1; i++) 83 + target[i] = '1' + random() % 9; 84 + target[sz - 1] = '\0'; 85 + 86 + ctx.skel->rodata->cmp_str_len = args.cmp_str_len; 87 + 88 + memcpy(ctx.skel->bss->str, target, args.cmp_str_len); 89 + ctx.skel->bss->str[args.cmp_str_len] = '\0'; 90 + /* Make bss->str < rodata->target */ 91 + ctx.skel->bss->str[args.cmp_str_len - 1] -= 1; 92 + 93 + err = strncmp_bench__load(ctx.skel); 94 + if (err) { 95 + fprintf(stderr, "failed to load skeleton\n"); 96 + strncmp_bench__destroy(ctx.skel); 97 + exit(1); 98 + } 99 + } 100 + 101 + static void strncmp_attach_prog(struct bpf_program *prog) 102 + { 103 + struct bpf_link *link; 104 + 105 + link = bpf_program__attach(prog); 106 + if (!link) { 107 + fprintf(stderr, "failed to attach program!\n"); 108 + exit(1); 109 + } 110 + } 111 + 112 + static void strncmp_no_helper_setup(void) 113 + { 114 + strncmp_setup(); 115 + strncmp_attach_prog(ctx.skel->progs.strncmp_no_helper); 116 + } 117 + 118 + static void strncmp_helper_setup(void) 119 + { 120 + strncmp_setup(); 121 + strncmp_attach_prog(ctx.skel->progs.strncmp_helper); 122 + } 123 + 124 + static void *strncmp_producer(void *ctx) 125 + { 126 + while (true) 127 + (void)syscall(__NR_getpgid); 128 + return NULL; 129 + } 130 + 131 + static void *strncmp_consumer(void *ctx) 132 + { 133 + return NULL; 134 + } 135 + 136 + static void strncmp_measure(struct bench_res *res) 137 + { 138 + res->hits = atomic_swap(&ctx.skel->bss->hits, 0); 139 + } 140 + 141 + const struct bench bench_strncmp_no_helper = { 142 + .name = "strncmp-no-helper", 143 + .validate = strncmp_validate, 144 + .setup = strncmp_no_helper_setup, 145 + .producer_thread = strncmp_producer, 146 + .consumer_thread = strncmp_consumer, 147 + .measure = strncmp_measure, 148 + .report_progress = hits_drops_report_progress, 149 + .report_final = hits_drops_report_final, 150 + }; 151 + 152 + const struct bench bench_strncmp_helper = { 153 + .name = "strncmp-helper", 154 + .validate = strncmp_validate, 155 + .setup = strncmp_helper_setup, 156 + .producer_thread = strncmp_producer, 157 + .consumer_thread = strncmp_consumer, 158 + .measure = strncmp_measure, 159 + .report_progress = hits_drops_report_progress, 160 + .report_final = hits_drops_report_final, 161 + };
+12 -12
tools/testing/selftests/bpf/benchs/bench_trigger.c
··· 11 11 12 12 static struct counter base_hits; 13 13 14 - static void trigger_validate() 14 + static void trigger_validate(void) 15 15 { 16 16 if (env.consumer_cnt != 1) { 17 17 fprintf(stderr, "benchmark doesn't support multi-consumer!\n"); ··· 45 45 res->hits = atomic_swap(&ctx.skel->bss->hits, 0); 46 46 } 47 47 48 - static void setup_ctx() 48 + static void setup_ctx(void) 49 49 { 50 50 setup_libbpf(); 51 51 ··· 67 67 } 68 68 } 69 69 70 - static void trigger_tp_setup() 70 + static void trigger_tp_setup(void) 71 71 { 72 72 setup_ctx(); 73 73 attach_bpf(ctx.skel->progs.bench_trigger_tp); 74 74 } 75 75 76 - static void trigger_rawtp_setup() 76 + static void trigger_rawtp_setup(void) 77 77 { 78 78 setup_ctx(); 79 79 attach_bpf(ctx.skel->progs.bench_trigger_raw_tp); 80 80 } 81 81 82 - static void trigger_kprobe_setup() 82 + static void trigger_kprobe_setup(void) 83 83 { 84 84 setup_ctx(); 85 85 attach_bpf(ctx.skel->progs.bench_trigger_kprobe); 86 86 } 87 87 88 - static void trigger_fentry_setup() 88 + static void trigger_fentry_setup(void) 89 89 { 90 90 setup_ctx(); 91 91 attach_bpf(ctx.skel->progs.bench_trigger_fentry); 92 92 } 93 93 94 - static void trigger_fentry_sleep_setup() 94 + static void trigger_fentry_sleep_setup(void) 95 95 { 96 96 setup_ctx(); 97 97 attach_bpf(ctx.skel->progs.bench_trigger_fentry_sleep); 98 98 } 99 99 100 - static void trigger_fmodret_setup() 100 + static void trigger_fmodret_setup(void) 101 101 { 102 102 setup_ctx(); 103 103 attach_bpf(ctx.skel->progs.bench_trigger_fmodret); ··· 183 183 ctx.skel->links.bench_trigger_uprobe = link; 184 184 } 185 185 186 - static void uprobe_setup_with_nop() 186 + static void uprobe_setup_with_nop(void) 187 187 { 188 188 usetup(false, true); 189 189 } 190 190 191 - static void uretprobe_setup_with_nop() 191 + static void uretprobe_setup_with_nop(void) 192 192 { 193 193 usetup(true, true); 194 194 } 195 195 196 - static void uprobe_setup_without_nop() 196 + static void uprobe_setup_without_nop(void) 197 197 { 198 198 usetup(false, false); 199 199 } 200 200 201 - static void uretprobe_setup_without_nop() 201 + static void uretprobe_setup_without_nop(void) 202 202 { 203 203 usetup(true, false); 204 204 }
+12
tools/testing/selftests/bpf/benchs/run_bench_strncmp.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + source ./benchs/run_common.sh 5 + 6 + set -eufo pipefail 7 + 8 + for s in 1 8 64 512 2048 4095; do 9 + for b in no-helper helper; do 10 + summarize ${b}-${s} "$($RUN_BENCH --cmp-str-len=$s strncmp-${b})" 11 + done 12 + done
+2
tools/testing/selftests/bpf/config
··· 38 38 CONFIG_BPF_JIT=y 39 39 CONFIG_BPF_LSM=y 40 40 CONFIG_SECURITY=y 41 + CONFIG_RC_CORE=y 41 42 CONFIG_LIRC=y 43 + CONFIG_BPF_LIRC_MODE2=y 42 44 CONFIG_IMA=y 43 45 CONFIG_SECURITYFS=y 44 46 CONFIG_IMA_WRITE_POLICY=y
+103 -88
tools/testing/selftests/bpf/prog_tests/align.c
··· 39 39 }, 40 40 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 41 41 .matches = { 42 - {1, "R1=ctx(id=0,off=0,imm=0)"}, 43 - {1, "R10=fp0"}, 44 - {1, "R3_w=inv2"}, 45 - {2, "R3_w=inv4"}, 46 - {3, "R3_w=inv8"}, 47 - {4, "R3_w=inv16"}, 48 - {5, "R3_w=inv32"}, 42 + {0, "R1=ctx(id=0,off=0,imm=0)"}, 43 + {0, "R10=fp0"}, 44 + {0, "R3_w=inv2"}, 45 + {1, "R3_w=inv4"}, 46 + {2, "R3_w=inv8"}, 47 + {3, "R3_w=inv16"}, 48 + {4, "R3_w=inv32"}, 49 49 }, 50 50 }, 51 51 { ··· 67 67 }, 68 68 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 69 69 .matches = { 70 - {1, "R1=ctx(id=0,off=0,imm=0)"}, 71 - {1, "R10=fp0"}, 72 - {1, "R3_w=inv1"}, 73 - {2, "R3_w=inv2"}, 74 - {3, "R3_w=inv4"}, 75 - {4, "R3_w=inv8"}, 76 - {5, "R3_w=inv16"}, 77 - {6, "R3_w=inv1"}, 78 - {7, "R4_w=inv32"}, 79 - {8, "R4_w=inv16"}, 80 - {9, "R4_w=inv8"}, 81 - {10, "R4_w=inv4"}, 82 - {11, "R4_w=inv2"}, 70 + {0, "R1=ctx(id=0,off=0,imm=0)"}, 71 + {0, "R10=fp0"}, 72 + {0, "R3_w=inv1"}, 73 + {1, "R3_w=inv2"}, 74 + {2, "R3_w=inv4"}, 75 + {3, "R3_w=inv8"}, 76 + {4, "R3_w=inv16"}, 77 + {5, "R3_w=inv1"}, 78 + {6, "R4_w=inv32"}, 79 + {7, "R4_w=inv16"}, 80 + {8, "R4_w=inv8"}, 81 + {9, "R4_w=inv4"}, 82 + {10, "R4_w=inv2"}, 83 83 }, 84 84 }, 85 85 { ··· 96 96 }, 97 97 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 98 98 .matches = { 99 - {1, "R1=ctx(id=0,off=0,imm=0)"}, 100 - {1, "R10=fp0"}, 101 - {1, "R3_w=inv4"}, 102 - {2, "R3_w=inv8"}, 103 - {3, "R3_w=inv10"}, 104 - {4, "R4_w=inv8"}, 105 - {5, "R4_w=inv12"}, 106 - {6, "R4_w=inv14"}, 99 + {0, "R1=ctx(id=0,off=0,imm=0)"}, 100 + {0, "R10=fp0"}, 101 + {0, "R3_w=inv4"}, 102 + {1, "R3_w=inv8"}, 103 + {2, "R3_w=inv10"}, 104 + {3, "R4_w=inv8"}, 105 + {4, "R4_w=inv12"}, 106 + {5, "R4_w=inv14"}, 107 107 }, 108 108 }, 109 109 { ··· 118 118 }, 119 119 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 120 120 .matches = { 121 - {1, "R1=ctx(id=0,off=0,imm=0)"}, 122 - {1, "R10=fp0"}, 121 + {0, "R1=ctx(id=0,off=0,imm=0)"}, 122 + {0, "R10=fp0"}, 123 + {0, "R3_w=inv7"}, 123 124 {1, "R3_w=inv7"}, 124 - {2, "R3_w=inv7"}, 125 - {3, "R3_w=inv14"}, 126 - {4, "R3_w=inv56"}, 125 + {2, "R3_w=inv14"}, 126 + {3, "R3_w=inv56"}, 127 127 }, 128 128 }, 129 129 ··· 161 161 }, 162 162 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 163 163 .matches = { 164 - {7, "R0_w=pkt(id=0,off=8,r=8,imm=0)"}, 165 - {7, "R3_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"}, 166 - {8, "R3_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"}, 167 - {9, "R3_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 168 - {10, "R3_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"}, 169 - {11, "R3_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"}, 170 - {18, "R3=pkt_end(id=0,off=0,imm=0)"}, 171 - {18, "R4_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"}, 172 - {19, "R4_w=inv(id=0,umax_value=8160,var_off=(0x0; 0x1fe0))"}, 173 - {20, "R4_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"}, 174 - {21, "R4_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"}, 175 - {22, "R4_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 176 - {23, "R4_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"}, 164 + {6, "R0_w=pkt(id=0,off=8,r=8,imm=0)"}, 165 + {6, "R3_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"}, 166 + {7, "R3_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"}, 167 + {8, "R3_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 168 + {9, "R3_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"}, 169 + {10, "R3_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"}, 170 + {12, "R3_w=pkt_end(id=0,off=0,imm=0)"}, 171 + {17, "R4_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"}, 172 + {18, "R4_w=inv(id=0,umax_value=8160,var_off=(0x0; 0x1fe0))"}, 173 + {19, "R4_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"}, 174 + {20, "R4_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"}, 175 + {21, "R4_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 176 + {22, "R4_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"}, 177 177 }, 178 178 }, 179 179 { ··· 194 194 }, 195 195 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 196 196 .matches = { 197 - {7, "R3_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"}, 198 - {8, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"}, 199 - {9, "R4_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"}, 200 - {10, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"}, 201 - {11, "R4_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"}, 202 - {12, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"}, 203 - {13, "R4_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 204 - {14, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"}, 205 - {15, "R4_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"}, 206 - {16, "R4_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"}, 197 + {6, "R3_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"}, 198 + {7, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"}, 199 + {8, "R4_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"}, 200 + {9, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"}, 201 + {10, "R4_w=inv(id=0,umax_value=510,var_off=(0x0; 0x1fe))"}, 202 + {11, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"}, 203 + {12, "R4_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 204 + {13, "R4_w=inv(id=1,umax_value=255,var_off=(0x0; 0xff))"}, 205 + {14, "R4_w=inv(id=0,umax_value=2040,var_off=(0x0; 0x7f8))"}, 206 + {15, "R4_w=inv(id=0,umax_value=4080,var_off=(0x0; 0xff0))"}, 207 207 }, 208 208 }, 209 209 { ··· 234 234 }, 235 235 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 236 236 .matches = { 237 - {4, "R5_w=pkt(id=0,off=0,r=0,imm=0)"}, 238 - {5, "R5_w=pkt(id=0,off=14,r=0,imm=0)"}, 239 - {6, "R4_w=pkt(id=0,off=14,r=0,imm=0)"}, 240 - {10, "R2=pkt(id=0,off=0,r=18,imm=0)"}, 237 + {2, "R5_w=pkt(id=0,off=0,r=0,imm=0)"}, 238 + {4, "R5_w=pkt(id=0,off=14,r=0,imm=0)"}, 239 + {5, "R4_w=pkt(id=0,off=14,r=0,imm=0)"}, 240 + {9, "R2=pkt(id=0,off=0,r=18,imm=0)"}, 241 241 {10, "R5=pkt(id=0,off=14,r=18,imm=0)"}, 242 242 {10, "R4_w=inv(id=0,umax_value=255,var_off=(0x0; 0xff))"}, 243 + {13, "R4_w=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff))"}, 243 244 {14, "R4_w=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff))"}, 244 - {15, "R4_w=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff))"}, 245 245 }, 246 246 }, 247 247 { ··· 296 296 /* Calculated offset in R6 has unknown value, but known 297 297 * alignment of 4. 298 298 */ 299 - {8, "R2_w=pkt(id=0,off=0,r=8,imm=0)"}, 300 - {8, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 299 + {6, "R2_w=pkt(id=0,off=0,r=8,imm=0)"}, 300 + {7, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 301 301 /* Offset is added to packet pointer R5, resulting in 302 302 * known fixed offset, and variable offset from R6. 303 303 */ ··· 313 313 /* Variable offset is added to R5 packet pointer, 314 314 * resulting in auxiliary alignment of 4. 315 315 */ 316 - {18, "R5_w=pkt(id=2,off=0,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 316 + {17, "R5_w=pkt(id=2,off=0,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 317 317 /* Constant offset is added to R5, resulting in 318 318 * reg->off of 14. 319 319 */ 320 - {19, "R5_w=pkt(id=2,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 320 + {18, "R5_w=pkt(id=2,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 321 321 /* At the time the word size load is performed from R5, 322 322 * its total fixed offset is NET_IP_ALIGN + reg->off 323 323 * (14) which is 16. Then the variable offset is 4-byte ··· 329 329 /* Constant offset is added to R5 packet pointer, 330 330 * resulting in reg->off value of 14. 331 331 */ 332 - {26, "R5_w=pkt(id=0,off=14,r=8"}, 332 + {25, "R5_w=pkt(id=0,off=14,r=8"}, 333 333 /* Variable offset is added to R5, resulting in a 334 334 * variable offset of (4n). 335 335 */ 336 - {27, "R5_w=pkt(id=3,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 336 + {26, "R5_w=pkt(id=3,off=14,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 337 337 /* Constant is added to R5 again, setting reg->off to 18. */ 338 - {28, "R5_w=pkt(id=3,off=18,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 338 + {27, "R5_w=pkt(id=3,off=18,r=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 339 339 /* And once more we add a variable; resulting var_off 340 340 * is still (4n), fixed offset is not changed. 341 341 * Also, we create a new reg->id. 342 342 */ 343 - {29, "R5_w=pkt(id=4,off=18,r=0,umax_value=2040,var_off=(0x0; 0x7fc)"}, 343 + {28, "R5_w=pkt(id=4,off=18,r=0,umax_value=2040,var_off=(0x0; 0x7fc)"}, 344 344 /* At the time the word size load is performed from R5, 345 345 * its total fixed offset is NET_IP_ALIGN + reg->off (18) 346 346 * which is 20. Then the variable offset is (4n), so ··· 386 386 /* Calculated offset in R6 has unknown value, but known 387 387 * alignment of 4. 388 388 */ 389 - {8, "R2_w=pkt(id=0,off=0,r=8,imm=0)"}, 390 - {8, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 389 + {6, "R2_w=pkt(id=0,off=0,r=8,imm=0)"}, 390 + {7, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 391 391 /* Adding 14 makes R6 be (4n+2) */ 392 - {9, "R6_w=inv(id=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))"}, 392 + {8, "R6_w=inv(id=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))"}, 393 393 /* Packet pointer has (4n+2) offset */ 394 394 {11, "R5_w=pkt(id=1,off=0,r=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc)"}, 395 - {13, "R4=pkt(id=1,off=4,r=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc)"}, 395 + {12, "R4=pkt(id=1,off=4,r=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc)"}, 396 396 /* At the time the word size load is performed from R5, 397 397 * its total fixed offset is NET_IP_ALIGN + reg->off (0) 398 398 * which is 2. Then the variable offset is (4n+2), so ··· 403 403 /* Newly read value in R6 was shifted left by 2, so has 404 404 * known alignment of 4. 405 405 */ 406 - {18, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 406 + {17, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 407 407 /* Added (4n) to packet pointer's (4n+2) var_off, giving 408 408 * another (4n+2). 409 409 */ 410 410 {19, "R5_w=pkt(id=2,off=0,r=0,umin_value=14,umax_value=2054,var_off=(0x2; 0xffc)"}, 411 - {21, "R4=pkt(id=2,off=4,r=0,umin_value=14,umax_value=2054,var_off=(0x2; 0xffc)"}, 411 + {20, "R4=pkt(id=2,off=4,r=0,umin_value=14,umax_value=2054,var_off=(0x2; 0xffc)"}, 412 412 /* At the time the word size load is performed from R5, 413 413 * its total fixed offset is NET_IP_ALIGN + reg->off (0) 414 414 * which is 2. Then the variable offset is (4n+2), so ··· 448 448 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 449 449 .result = REJECT, 450 450 .matches = { 451 - {4, "R5_w=pkt_end(id=0,off=0,imm=0)"}, 451 + {3, "R5_w=pkt_end(id=0,off=0,imm=0)"}, 452 452 /* (ptr - ptr) << 2 == unknown, (4n) */ 453 - {6, "R5_w=inv(id=0,smax_value=9223372036854775804,umax_value=18446744073709551612,var_off=(0x0; 0xfffffffffffffffc)"}, 453 + {5, "R5_w=inv(id=0,smax_value=9223372036854775804,umax_value=18446744073709551612,var_off=(0x0; 0xfffffffffffffffc)"}, 454 454 /* (4n) + 14 == (4n+2). We blow our bounds, because 455 455 * the add could overflow. 456 456 */ 457 - {7, "R5_w=inv(id=0,smin_value=-9223372036854775806,smax_value=9223372036854775806,umin_value=2,umax_value=18446744073709551614,var_off=(0x2; 0xfffffffffffffffc)"}, 457 + {6, "R5_w=inv(id=0,smin_value=-9223372036854775806,smax_value=9223372036854775806,umin_value=2,umax_value=18446744073709551614,var_off=(0x2; 0xfffffffffffffffc)"}, 458 458 /* Checked s>=0 */ 459 459 {9, "R5=inv(id=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"}, 460 460 /* packet pointer + nonnegative (4n+2) */ 461 461 {11, "R6_w=pkt(id=1,off=0,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"}, 462 - {13, "R4_w=pkt(id=1,off=4,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"}, 462 + {12, "R4_w=pkt(id=1,off=4,r=0,umin_value=2,umax_value=9223372036854775806,var_off=(0x2; 0x7ffffffffffffffc)"}, 463 463 /* NET_IP_ALIGN + (4n+2) == (4n), alignment is fine. 464 464 * We checked the bounds, but it might have been able 465 465 * to overflow if the packet pointer started in the ··· 502 502 /* Calculated offset in R6 has unknown value, but known 503 503 * alignment of 4. 504 504 */ 505 - {7, "R2_w=pkt(id=0,off=0,r=8,imm=0)"}, 506 - {9, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 505 + {6, "R2_w=pkt(id=0,off=0,r=8,imm=0)"}, 506 + {8, "R6_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 507 507 /* Adding 14 makes R6 be (4n+2) */ 508 - {10, "R6_w=inv(id=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))"}, 508 + {9, "R6_w=inv(id=0,umin_value=14,umax_value=1034,var_off=(0x2; 0x7fc))"}, 509 509 /* New unknown value in R7 is (4n) */ 510 - {11, "R7_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 510 + {10, "R7_w=inv(id=0,umax_value=1020,var_off=(0x0; 0x3fc))"}, 511 511 /* Subtracting it from R6 blows our unsigned bounds */ 512 - {12, "R6=inv(id=0,smin_value=-1006,smax_value=1034,umin_value=2,umax_value=18446744073709551614,var_off=(0x2; 0xfffffffffffffffc)"}, 512 + {11, "R6=inv(id=0,smin_value=-1006,smax_value=1034,umin_value=2,umax_value=18446744073709551614,var_off=(0x2; 0xfffffffffffffffc)"}, 513 513 /* Checked s>= 0 */ 514 514 {14, "R6=inv(id=0,umin_value=2,umax_value=1034,var_off=(0x2; 0x7fc))"}, 515 515 /* At the time the word size load is performed from R5, ··· 556 556 /* Calculated offset in R6 has unknown value, but known 557 557 * alignment of 4. 558 558 */ 559 - {7, "R2_w=pkt(id=0,off=0,r=8,imm=0)"}, 560 - {10, "R6_w=inv(id=0,umax_value=60,var_off=(0x0; 0x3c))"}, 559 + {6, "R2_w=pkt(id=0,off=0,r=8,imm=0)"}, 560 + {9, "R6_w=inv(id=0,umax_value=60,var_off=(0x0; 0x3c))"}, 561 561 /* Adding 14 makes R6 be (4n+2) */ 562 - {11, "R6_w=inv(id=0,umin_value=14,umax_value=74,var_off=(0x2; 0x7c))"}, 562 + {10, "R6_w=inv(id=0,umin_value=14,umax_value=74,var_off=(0x2; 0x7c))"}, 563 563 /* Subtracting from packet pointer overflows ubounds */ 564 564 {13, "R5_w=pkt(id=2,off=0,r=8,umin_value=18446744073709551542,umax_value=18446744073709551602,var_off=(0xffffffffffffff82; 0x7c)"}, 565 565 /* New unknown value in R7 is (4n), >= 76 */ 566 - {15, "R7_w=inv(id=0,umin_value=76,umax_value=1096,var_off=(0x0; 0x7fc))"}, 566 + {14, "R7_w=inv(id=0,umin_value=76,umax_value=1096,var_off=(0x0; 0x7fc))"}, 567 567 /* Adding it to packet pointer gives nice bounds again */ 568 568 {16, "R5_w=pkt(id=3,off=0,r=0,umin_value=2,umax_value=1082,var_off=(0x2; 0xfffffffc)"}, 569 569 /* At the time the word size load is performed from R5, ··· 625 625 line_ptr = strtok(bpf_vlog_copy, "\n"); 626 626 for (i = 0; i < MAX_MATCHES; i++) { 627 627 struct bpf_reg_match m = test->matches[i]; 628 + int tmp; 628 629 629 630 if (!m.match) 630 631 break; 631 632 while (line_ptr) { 632 633 cur_line = -1; 633 634 sscanf(line_ptr, "%u: ", &cur_line); 635 + if (cur_line == -1) 636 + sscanf(line_ptr, "from %u to %u: ", &tmp, &cur_line); 634 637 if (cur_line == m.line) 635 638 break; 636 639 line_ptr = strtok(NULL, "\n"); ··· 645 642 printf("%s", bpf_vlog); 646 643 break; 647 644 } 645 + /* Check the next line as well in case the previous line 646 + * did not have a corresponding bpf insn. Example: 647 + * func#0 @0 648 + * 0: R1=ctx(id=0,off=0,imm=0) R10=fp0 649 + * 0: (b7) r3 = 2 ; R3_w=inv2 650 + */ 648 651 if (!strstr(line_ptr, m.match)) { 652 + cur_line = -1; 653 + line_ptr = strtok(NULL, "\n"); 654 + sscanf(line_ptr, "%u: ", &cur_line); 655 + } 656 + if (cur_line != m.line || !line_ptr || 657 + !strstr(line_ptr, m.match)) { 649 658 printf("Failed to find match %u: %s\n", 650 659 m.line, m.match); 651 660 ret = 1;
+2 -2
tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c
··· 65 65 if (CHECK_FAIL(err)) 66 66 goto done; 67 67 68 - prog = bpf_object__find_program_by_title(objs[i], 69 - "raw_tp/sys_enter"); 68 + prog = bpf_object__find_program_by_name(objs[i], 69 + "test_obj_id"); 70 70 if (CHECK_FAIL(!prog)) 71 71 goto done; 72 72 links[i] = bpf_program__attach(prog);
+3 -4
tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
··· 217 217 static int libbpf_debug_print(enum libbpf_print_level level, 218 218 const char *format, va_list args) 219 219 { 220 - const char *log_buf; 220 + const char *prog_name, *log_buf; 221 221 222 222 if (level != LIBBPF_WARN || 223 223 !strstr(format, "-- BEGIN PROG LOAD LOG --")) { ··· 225 225 return 0; 226 226 } 227 227 228 - /* skip prog_name */ 229 - va_arg(args, char *); 228 + prog_name = va_arg(args, char *); 230 229 log_buf = va_arg(args, char *); 231 230 if (!log_buf) 232 231 goto out; 233 232 if (err_str && strstr(log_buf, err_str) != NULL) 234 233 found = true; 235 234 out: 236 - printf(format, log_buf); 235 + printf(format, prog_name, log_buf); 237 236 return 0; 238 237 } 239 238
-1
tools/testing/selftests/bpf/prog_tests/btf.c
··· 22 22 #include <bpf/libbpf.h> 23 23 #include <bpf/btf.h> 24 24 25 - #include "bpf_rlimit.h" 26 25 #include "bpf_util.h" 27 26 #include "../test_btf.h" 28 27 #include "test_progs.h"
+9 -9
tools/testing/selftests/bpf/prog_tests/connect_force_port.c
··· 67 67 goto close_bpf_object; 68 68 } 69 69 70 - prog = bpf_object__find_program_by_title(obj, v4 ? 71 - "cgroup/connect4" : 72 - "cgroup/connect6"); 70 + prog = bpf_object__find_program_by_name(obj, v4 ? 71 + "connect4" : 72 + "connect6"); 73 73 if (CHECK(!prog, "find_prog", "connect prog not found\n")) { 74 74 err = -EIO; 75 75 goto close_bpf_object; ··· 83 83 goto close_bpf_object; 84 84 } 85 85 86 - prog = bpf_object__find_program_by_title(obj, v4 ? 87 - "cgroup/getpeername4" : 88 - "cgroup/getpeername6"); 86 + prog = bpf_object__find_program_by_name(obj, v4 ? 87 + "getpeername4" : 88 + "getpeername6"); 89 89 if (CHECK(!prog, "find_prog", "getpeername prog not found\n")) { 90 90 err = -EIO; 91 91 goto close_bpf_object; ··· 99 99 goto close_bpf_object; 100 100 } 101 101 102 - prog = bpf_object__find_program_by_title(obj, v4 ? 103 - "cgroup/getsockname4" : 104 - "cgroup/getsockname6"); 102 + prog = bpf_object__find_program_by_name(obj, v4 ? 103 + "getsockname4" : 104 + "getsockname6"); 105 105 if (CHECK(!prog, "find_prog", "getsockname prog not found\n")) { 106 106 err = -EIO; 107 107 goto close_bpf_object;
+53 -26
tools/testing/selftests/bpf/prog_tests/core_reloc.c
··· 10 10 11 11 #define STRUCT_TO_CHAR_PTR(struct_name) (const char *)&(struct struct_name) 12 12 13 - #define MODULES_CASE(name, sec_name, tp_name) { \ 13 + #define MODULES_CASE(name, pg_name, tp_name) { \ 14 14 .case_name = name, \ 15 15 .bpf_obj_file = "test_core_reloc_module.o", \ 16 16 .btf_src_file = NULL, /* find in kernel module BTFs */ \ ··· 28 28 .comm_len = sizeof("test_progs"), \ 29 29 }, \ 30 30 .output_len = sizeof(struct core_reloc_module_output), \ 31 - .prog_sec_name = sec_name, \ 31 + .prog_name = pg_name, \ 32 32 .raw_tp_name = tp_name, \ 33 33 .trigger = __trigger_module_test_read, \ 34 34 .needs_testmod = true, \ ··· 43 43 #define FLAVORS_CASE_COMMON(name) \ 44 44 .case_name = #name, \ 45 45 .bpf_obj_file = "test_core_reloc_flavors.o", \ 46 - .btf_src_file = "btf__core_reloc_" #name ".o" \ 46 + .btf_src_file = "btf__core_reloc_" #name ".o", \ 47 + .raw_tp_name = "sys_enter", \ 48 + .prog_name = "test_core_flavors" \ 47 49 48 50 #define FLAVORS_CASE(name) { \ 49 51 FLAVORS_CASE_COMMON(name), \ ··· 68 66 #define NESTING_CASE_COMMON(name) \ 69 67 .case_name = #name, \ 70 68 .bpf_obj_file = "test_core_reloc_nesting.o", \ 71 - .btf_src_file = "btf__core_reloc_" #name ".o" 69 + .btf_src_file = "btf__core_reloc_" #name ".o", \ 70 + .raw_tp_name = "sys_enter", \ 71 + .prog_name = "test_core_nesting" \ 72 72 73 73 #define NESTING_CASE(name) { \ 74 74 NESTING_CASE_COMMON(name), \ ··· 95 91 #define ARRAYS_CASE_COMMON(name) \ 96 92 .case_name = #name, \ 97 93 .bpf_obj_file = "test_core_reloc_arrays.o", \ 98 - .btf_src_file = "btf__core_reloc_" #name ".o" 94 + .btf_src_file = "btf__core_reloc_" #name ".o", \ 95 + .raw_tp_name = "sys_enter", \ 96 + .prog_name = "test_core_arrays" \ 99 97 100 98 #define ARRAYS_CASE(name) { \ 101 99 ARRAYS_CASE_COMMON(name), \ ··· 129 123 #define PRIMITIVES_CASE_COMMON(name) \ 130 124 .case_name = #name, \ 131 125 .bpf_obj_file = "test_core_reloc_primitives.o", \ 132 - .btf_src_file = "btf__core_reloc_" #name ".o" 126 + .btf_src_file = "btf__core_reloc_" #name ".o", \ 127 + .raw_tp_name = "sys_enter", \ 128 + .prog_name = "test_core_primitives" \ 133 129 134 130 #define PRIMITIVES_CASE(name) { \ 135 131 PRIMITIVES_CASE_COMMON(name), \ ··· 166 158 .e = 5, .f = 6, .g = 7, .h = 8, \ 167 159 }, \ 168 160 .output_len = sizeof(struct core_reloc_mods_output), \ 161 + .raw_tp_name = "sys_enter", \ 162 + .prog_name = "test_core_mods", \ 169 163 } 170 164 171 165 #define PTR_AS_ARR_CASE(name) { \ ··· 184 174 .a = 3, \ 185 175 }, \ 186 176 .output_len = sizeof(struct core_reloc_ptr_as_arr), \ 177 + .raw_tp_name = "sys_enter", \ 178 + .prog_name = "test_core_ptr_as_arr", \ 187 179 } 188 180 189 181 #define INTS_DATA(struct_name) STRUCT_TO_CHAR_PTR(struct_name) { \ ··· 202 190 #define INTS_CASE_COMMON(name) \ 203 191 .case_name = #name, \ 204 192 .bpf_obj_file = "test_core_reloc_ints.o", \ 205 - .btf_src_file = "btf__core_reloc_" #name ".o" 193 + .btf_src_file = "btf__core_reloc_" #name ".o", \ 194 + .raw_tp_name = "sys_enter", \ 195 + .prog_name = "test_core_ints" 206 196 207 197 #define INTS_CASE(name) { \ 208 198 INTS_CASE_COMMON(name), \ ··· 222 208 #define FIELD_EXISTS_CASE_COMMON(name) \ 223 209 .case_name = #name, \ 224 210 .bpf_obj_file = "test_core_reloc_existence.o", \ 225 - .btf_src_file = "btf__core_reloc_" #name ".o" \ 211 + .btf_src_file = "btf__core_reloc_" #name ".o", \ 212 + .raw_tp_name = "sys_enter", \ 213 + .prog_name = "test_core_existence" 226 214 227 215 #define BITFIELDS_CASE_COMMON(objfile, test_name_prefix, name) \ 228 216 .case_name = test_name_prefix#name, \ ··· 239 223 .output = STRUCT_TO_CHAR_PTR(core_reloc_bitfields_output) \ 240 224 __VA_ARGS__, \ 241 225 .output_len = sizeof(struct core_reloc_bitfields_output), \ 226 + .raw_tp_name = "sys_enter", \ 227 + .prog_name = "test_core_bitfields", \ 242 228 }, { \ 243 229 BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_direct.o", \ 244 230 "direct:", name), \ ··· 249 231 .output = STRUCT_TO_CHAR_PTR(core_reloc_bitfields_output) \ 250 232 __VA_ARGS__, \ 251 233 .output_len = sizeof(struct core_reloc_bitfields_output), \ 252 - .prog_sec_name = "tp_btf/sys_enter", \ 234 + .prog_name = "test_core_bitfields_direct", \ 253 235 } 254 236 255 237 ··· 257 239 BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_probed.o", \ 258 240 "probed:", name), \ 259 241 .fails = true, \ 242 + .raw_tp_name = "sys_enter", \ 243 + .prog_name = "test_core_bitfields", \ 260 244 }, { \ 261 245 BITFIELDS_CASE_COMMON("test_core_reloc_bitfields_direct.o", \ 262 246 "direct:", name), \ 263 - .prog_sec_name = "tp_btf/sys_enter", \ 264 247 .fails = true, \ 248 + .prog_name = "test_core_bitfields_direct", \ 265 249 } 266 250 267 251 #define SIZE_CASE_COMMON(name) \ 268 252 .case_name = #name, \ 269 253 .bpf_obj_file = "test_core_reloc_size.o", \ 270 - .btf_src_file = "btf__core_reloc_" #name ".o" 254 + .btf_src_file = "btf__core_reloc_" #name ".o", \ 255 + .raw_tp_name = "sys_enter", \ 256 + .prog_name = "test_core_size" 271 257 272 258 #define SIZE_OUTPUT_DATA(type) \ 273 259 STRUCT_TO_CHAR_PTR(core_reloc_size_output) { \ ··· 299 277 300 278 #define TYPE_BASED_CASE_COMMON(name) \ 301 279 .case_name = #name, \ 302 - .bpf_obj_file = "test_core_reloc_type_based.o", \ 303 - .btf_src_file = "btf__core_reloc_" #name ".o" \ 280 + .bpf_obj_file = "test_core_reloc_type_based.o", \ 281 + .btf_src_file = "btf__core_reloc_" #name ".o", \ 282 + .raw_tp_name = "sys_enter", \ 283 + .prog_name = "test_core_type_based" 304 284 305 285 #define TYPE_BASED_CASE(name, ...) { \ 306 286 TYPE_BASED_CASE_COMMON(name), \ ··· 319 295 #define TYPE_ID_CASE_COMMON(name) \ 320 296 .case_name = #name, \ 321 297 .bpf_obj_file = "test_core_reloc_type_id.o", \ 322 - .btf_src_file = "btf__core_reloc_" #name ".o" \ 298 + .btf_src_file = "btf__core_reloc_" #name ".o", \ 299 + .raw_tp_name = "sys_enter", \ 300 + .prog_name = "test_core_type_id" 323 301 324 302 #define TYPE_ID_CASE(name, setup_fn) { \ 325 303 TYPE_ID_CASE_COMMON(name), \ ··· 338 312 #define ENUMVAL_CASE_COMMON(name) \ 339 313 .case_name = #name, \ 340 314 .bpf_obj_file = "test_core_reloc_enumval.o", \ 341 - .btf_src_file = "btf__core_reloc_" #name ".o" \ 315 + .btf_src_file = "btf__core_reloc_" #name ".o", \ 316 + .raw_tp_name = "sys_enter", \ 317 + .prog_name = "test_core_enumval" 342 318 343 319 #define ENUMVAL_CASE(name, ...) { \ 344 320 ENUMVAL_CASE_COMMON(name), \ ··· 370 342 bool fails; 371 343 bool needs_testmod; 372 344 bool relaxed_core_relocs; 373 - const char *prog_sec_name; 345 + const char *prog_name; 374 346 const char *raw_tp_name; 375 347 setup_test_fn setup; 376 348 trigger_test_fn trigger; ··· 525 497 .comm_len = sizeof("test_progs"), 526 498 }, 527 499 .output_len = sizeof(struct core_reloc_kernel_output), 500 + .raw_tp_name = "sys_enter", 501 + .prog_name = "test_core_kernel", 528 502 }, 529 503 530 504 /* validate we can find kernel module BTF types for relocs/attach */ 531 - MODULES_CASE("module_probed", "raw_tp/bpf_testmod_test_read", "bpf_testmod_test_read"), 532 - MODULES_CASE("module_direct", "tp_btf/bpf_testmod_test_read", NULL), 505 + MODULES_CASE("module_probed", "test_core_module_probed", "bpf_testmod_test_read"), 506 + MODULES_CASE("module_direct", "test_core_module_direct", NULL), 533 507 534 508 /* validate BPF program can use multiple flavors to match against 535 509 * single target BTF type ··· 610 580 .c = 0, /* BUG in clang, should be 3 */ 611 581 }, 612 582 .output_len = sizeof(struct core_reloc_misc_output), 583 + .raw_tp_name = "sys_enter", 584 + .prog_name = "test_core_misc", 613 585 }, 614 586 615 587 /* validate field existence checks */ ··· 880 848 if (!ASSERT_OK_PTR(obj, "obj_open")) 881 849 goto cleanup; 882 850 883 - probe_name = "raw_tracepoint/sys_enter"; 884 - tp_name = "sys_enter"; 885 - if (test_case->prog_sec_name) { 886 - probe_name = test_case->prog_sec_name; 887 - tp_name = test_case->raw_tp_name; /* NULL for tp_btf */ 888 - } 889 - 890 - prog = bpf_object__find_program_by_title(obj, probe_name); 851 + probe_name = test_case->prog_name; 852 + tp_name = test_case->raw_tp_name; /* NULL for tp_btf */ 853 + prog = bpf_object__find_program_by_name(obj, probe_name); 891 854 if (CHECK(!prog, "find_probe", 892 855 "prog '%s' not found\n", probe_name)) 893 856 goto cleanup;
+13 -4
tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c
··· 101 101 102 102 for (i = 0; i < prog_cnt; i++) { 103 103 struct bpf_link_info link_info; 104 + struct bpf_program *pos; 105 + const char *pos_sec_name; 104 106 char *tgt_name; 105 107 __s32 btf_id; 106 108 ··· 111 109 goto close_prog; 112 110 btf_id = btf__find_by_name_kind(btf, tgt_name + 1, BTF_KIND_FUNC); 113 111 114 - prog[i] = bpf_object__find_program_by_title(obj, prog_name[i]); 112 + prog[i] = NULL; 113 + bpf_object__for_each_program(pos, obj) { 114 + pos_sec_name = bpf_program__section_name(pos); 115 + if (pos_sec_name && !strcmp(pos_sec_name, prog_name[i])) { 116 + prog[i] = pos; 117 + break; 118 + } 119 + } 115 120 if (!ASSERT_OK_PTR(prog[i], prog_name[i])) 116 121 goto close_prog; 117 122 ··· 220 211 221 212 static int test_second_attach(struct bpf_object *obj) 222 213 { 223 - const char *prog_name = "freplace/get_constant"; 224 - const char *tgt_name = prog_name + 9; /* cut off freplace/ */ 214 + const char *prog_name = "security_new_get_constant"; 215 + const char *tgt_name = "get_constant"; 225 216 const char *tgt_obj_file = "./test_pkt_access.o"; 226 217 struct bpf_program *prog = NULL; 227 218 struct bpf_object *tgt_obj; ··· 229 220 struct bpf_link *link; 230 221 int err = 0, tgt_fd; 231 222 232 - prog = bpf_object__find_program_by_title(obj, prog_name); 223 + prog = bpf_object__find_program_by_name(obj, prog_name); 233 224 if (CHECK(!prog, "find_prog", "prog %s not found\n", prog_name)) 234 225 return -ENOENT; 235 226
+44
tools/testing/selftests/bpf/prog_tests/get_func_args_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <test_progs.h> 3 + #include "get_func_args_test.skel.h" 4 + 5 + void test_get_func_args_test(void) 6 + { 7 + struct get_func_args_test *skel = NULL; 8 + __u32 duration = 0, retval; 9 + int err, prog_fd; 10 + 11 + skel = get_func_args_test__open_and_load(); 12 + if (!ASSERT_OK_PTR(skel, "get_func_args_test__open_and_load")) 13 + return; 14 + 15 + err = get_func_args_test__attach(skel); 16 + if (!ASSERT_OK(err, "get_func_args_test__attach")) 17 + goto cleanup; 18 + 19 + /* This runs bpf_fentry_test* functions and triggers 20 + * fentry/fexit programs. 21 + */ 22 + prog_fd = bpf_program__fd(skel->progs.test1); 23 + err = bpf_prog_test_run(prog_fd, 1, NULL, 0, 24 + NULL, NULL, &retval, &duration); 25 + ASSERT_OK(err, "test_run"); 26 + ASSERT_EQ(retval, 0, "test_run"); 27 + 28 + /* This runs bpf_modify_return_test function and triggers 29 + * fmod_ret_test and fexit_test programs. 30 + */ 31 + prog_fd = bpf_program__fd(skel->progs.fmod_ret_test); 32 + err = bpf_prog_test_run(prog_fd, 1, NULL, 0, 33 + NULL, NULL, &retval, &duration); 34 + ASSERT_OK(err, "test_run"); 35 + ASSERT_EQ(retval, 1234, "test_run"); 36 + 37 + ASSERT_EQ(skel->bss->test1_result, 1, "test1_result"); 38 + ASSERT_EQ(skel->bss->test2_result, 1, "test2_result"); 39 + ASSERT_EQ(skel->bss->test3_result, 1, "test3_result"); 40 + ASSERT_EQ(skel->bss->test4_result, 1, "test4_result"); 41 + 42 + cleanup: 43 + get_func_args_test__destroy(skel); 44 + }
+2 -2
tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c
··· 89 89 { 90 90 const char *file = "./test_get_stack_rawtp.o"; 91 91 const char *file_err = "./test_get_stack_rawtp_err.o"; 92 - const char *prog_name = "raw_tracepoint/sys_enter"; 92 + const char *prog_name = "bpf_prog1"; 93 93 int i, err, prog_fd, exp_cnt = MAX_CNT_RAWTP; 94 94 struct perf_buffer *pb = NULL; 95 95 struct bpf_link *link = NULL; ··· 107 107 if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno)) 108 108 return; 109 109 110 - prog = bpf_object__find_program_by_title(obj, prog_name); 110 + prog = bpf_object__find_program_by_name(obj, prog_name); 111 111 if (CHECK(!prog, "find_probe", "prog '%s' not found\n", prog_name)) 112 112 goto close_prog; 113 113
+14
tools/testing/selftests/bpf/prog_tests/ksyms_btf.c
··· 8 8 #include "test_ksyms_btf_null_check.skel.h" 9 9 #include "test_ksyms_weak.skel.h" 10 10 #include "test_ksyms_weak.lskel.h" 11 + #include "test_ksyms_btf_write_check.skel.h" 11 12 12 13 static int duration; 13 14 ··· 138 137 test_ksyms_weak_lskel__destroy(skel); 139 138 } 140 139 140 + static void test_write_check(void) 141 + { 142 + struct test_ksyms_btf_write_check *skel; 143 + 144 + skel = test_ksyms_btf_write_check__open_and_load(); 145 + ASSERT_ERR_PTR(skel, "unexpected load of a prog writing to ksym memory\n"); 146 + 147 + test_ksyms_btf_write_check__destroy(skel); 148 + } 149 + 141 150 void test_ksyms_btf(void) 142 151 { 143 152 int percpu_datasec; ··· 178 167 179 168 if (test__start_subtest("weak_ksyms_lskel")) 180 169 test_weak_syms_lskel(); 170 + 171 + if (test__start_subtest("write_check")) 172 + test_write_check(); 181 173 }
+124
tools/testing/selftests/bpf/prog_tests/libbpf_probes.c
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Copyright (c) 2021 Facebook */ 3 + 4 + #include <test_progs.h> 5 + #include <bpf/btf.h> 6 + 7 + void test_libbpf_probe_prog_types(void) 8 + { 9 + struct btf *btf; 10 + const struct btf_type *t; 11 + const struct btf_enum *e; 12 + int i, n, id; 13 + 14 + btf = btf__parse("/sys/kernel/btf/vmlinux", NULL); 15 + if (!ASSERT_OK_PTR(btf, "btf_parse")) 16 + return; 17 + 18 + /* find enum bpf_prog_type and enumerate each value */ 19 + id = btf__find_by_name_kind(btf, "bpf_prog_type", BTF_KIND_ENUM); 20 + if (!ASSERT_GT(id, 0, "bpf_prog_type_id")) 21 + goto cleanup; 22 + t = btf__type_by_id(btf, id); 23 + if (!ASSERT_OK_PTR(t, "bpf_prog_type_enum")) 24 + goto cleanup; 25 + 26 + for (e = btf_enum(t), i = 0, n = btf_vlen(t); i < n; e++, i++) { 27 + const char *prog_type_name = btf__str_by_offset(btf, e->name_off); 28 + enum bpf_prog_type prog_type = (enum bpf_prog_type)e->val; 29 + int res; 30 + 31 + if (prog_type == BPF_PROG_TYPE_UNSPEC) 32 + continue; 33 + 34 + if (!test__start_subtest(prog_type_name)) 35 + continue; 36 + 37 + res = libbpf_probe_bpf_prog_type(prog_type, NULL); 38 + ASSERT_EQ(res, 1, prog_type_name); 39 + } 40 + 41 + cleanup: 42 + btf__free(btf); 43 + } 44 + 45 + void test_libbpf_probe_map_types(void) 46 + { 47 + struct btf *btf; 48 + const struct btf_type *t; 49 + const struct btf_enum *e; 50 + int i, n, id; 51 + 52 + btf = btf__parse("/sys/kernel/btf/vmlinux", NULL); 53 + if (!ASSERT_OK_PTR(btf, "btf_parse")) 54 + return; 55 + 56 + /* find enum bpf_map_type and enumerate each value */ 57 + id = btf__find_by_name_kind(btf, "bpf_map_type", BTF_KIND_ENUM); 58 + if (!ASSERT_GT(id, 0, "bpf_map_type_id")) 59 + goto cleanup; 60 + t = btf__type_by_id(btf, id); 61 + if (!ASSERT_OK_PTR(t, "bpf_map_type_enum")) 62 + goto cleanup; 63 + 64 + for (e = btf_enum(t), i = 0, n = btf_vlen(t); i < n; e++, i++) { 65 + const char *map_type_name = btf__str_by_offset(btf, e->name_off); 66 + enum bpf_map_type map_type = (enum bpf_map_type)e->val; 67 + int res; 68 + 69 + if (map_type == BPF_MAP_TYPE_UNSPEC) 70 + continue; 71 + 72 + if (!test__start_subtest(map_type_name)) 73 + continue; 74 + 75 + res = libbpf_probe_bpf_map_type(map_type, NULL); 76 + ASSERT_EQ(res, 1, map_type_name); 77 + } 78 + 79 + cleanup: 80 + btf__free(btf); 81 + } 82 + 83 + void test_libbpf_probe_helpers(void) 84 + { 85 + #define CASE(prog, helper, supp) { \ 86 + .prog_type_name = "BPF_PROG_TYPE_" # prog, \ 87 + .helper_name = "bpf_" # helper, \ 88 + .prog_type = BPF_PROG_TYPE_ ## prog, \ 89 + .helper_id = BPF_FUNC_ ## helper, \ 90 + .supported = supp, \ 91 + } 92 + const struct case_def { 93 + const char *prog_type_name; 94 + const char *helper_name; 95 + enum bpf_prog_type prog_type; 96 + enum bpf_func_id helper_id; 97 + bool supported; 98 + } cases[] = { 99 + CASE(KPROBE, unspec, false), 100 + CASE(KPROBE, map_lookup_elem, true), 101 + CASE(KPROBE, loop, true), 102 + 103 + CASE(KPROBE, ktime_get_coarse_ns, false), 104 + CASE(SOCKET_FILTER, ktime_get_coarse_ns, true), 105 + 106 + CASE(KPROBE, sys_bpf, false), 107 + CASE(SYSCALL, sys_bpf, true), 108 + }; 109 + size_t case_cnt = ARRAY_SIZE(cases), i; 110 + char buf[128]; 111 + 112 + for (i = 0; i < case_cnt; i++) { 113 + const struct case_def *d = &cases[i]; 114 + int res; 115 + 116 + snprintf(buf, sizeof(buf), "%s+%s", d->prog_type_name, d->helper_name); 117 + 118 + if (!test__start_subtest(buf)) 119 + continue; 120 + 121 + res = libbpf_probe_bpf_helper(d->prog_type, d->helper_id, NULL); 122 + ASSERT_EQ(res, d->supported, buf); 123 + } 124 + }
-1
tools/testing/selftests/bpf/prog_tests/select_reuseport.c
··· 18 18 #include <netinet/in.h> 19 19 #include <bpf/bpf.h> 20 20 #include <bpf/libbpf.h> 21 - #include "bpf_rlimit.h" 22 21 #include "bpf_util.h" 23 22 24 23 #include "test_progs.h"
-1
tools/testing/selftests/bpf/prog_tests/sk_lookup.c
··· 30 30 #include <bpf/bpf.h> 31 31 32 32 #include "test_progs.h" 33 - #include "bpf_rlimit.h" 34 33 #include "bpf_util.h" 35 34 #include "cgroup_helpers.h" 36 35 #include "network_helpers.h"
-1
tools/testing/selftests/bpf/prog_tests/sock_fields.c
··· 15 15 #include "network_helpers.h" 16 16 #include "cgroup_helpers.h" 17 17 #include "test_progs.h" 18 - #include "bpf_rlimit.h" 19 18 #include "test_sock_fields.skel.h" 20 19 21 20 enum bpf_linum_array_idx {
+8 -7
tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c
··· 136 136 return fd; 137 137 } 138 138 139 - static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) 139 + static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title, 140 + const char *prog_name) 140 141 { 141 142 enum bpf_attach_type attach_type; 142 143 enum bpf_prog_type prog_type; ··· 146 145 147 146 err = libbpf_prog_type_by_name(title, &prog_type, &attach_type); 148 147 if (err) { 149 - log_err("Failed to deduct types for %s BPF program", title); 148 + log_err("Failed to deduct types for %s BPF program", prog_name); 150 149 return -1; 151 150 } 152 151 153 - prog = bpf_object__find_program_by_title(obj, title); 152 + prog = bpf_object__find_program_by_name(obj, prog_name); 154 153 if (!prog) { 155 - log_err("Failed to find %s BPF program", title); 154 + log_err("Failed to find %s BPF program", prog_name); 156 155 return -1; 157 156 } 158 157 159 158 err = bpf_prog_attach(bpf_program__fd(prog), cgroup_fd, 160 159 attach_type, 0); 161 160 if (err) { 162 - log_err("Failed to attach %s BPF program", title); 161 + log_err("Failed to attach %s BPF program", prog_name); 163 162 return -1; 164 163 } 165 164 ··· 182 181 if (!ASSERT_OK(err, "obj_load")) 183 182 goto close_bpf_object; 184 183 185 - err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt"); 184 + err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt", "_getsockopt"); 186 185 if (CHECK_FAIL(err)) 187 186 goto close_bpf_object; 188 187 189 - err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt"); 188 + err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt", "_setsockopt"); 190 189 if (CHECK_FAIL(err)) 191 190 goto close_bpf_object; 192 191
+2 -2
tools/testing/selftests/bpf/prog_tests/stacktrace_map.c
··· 4 4 void test_stacktrace_map(void) 5 5 { 6 6 int control_map_fd, stackid_hmap_fd, stackmap_fd, stack_amap_fd; 7 - const char *prog_name = "tracepoint/sched/sched_switch"; 7 + const char *prog_name = "oncpu"; 8 8 int err, prog_fd, stack_trace_len; 9 9 const char *file = "./test_stacktrace_map.o"; 10 10 __u32 key, val, duration = 0; ··· 16 16 if (CHECK(err, "prog_load", "err %d errno %d\n", err, errno)) 17 17 return; 18 18 19 - prog = bpf_object__find_program_by_title(obj, prog_name); 19 + prog = bpf_object__find_program_by_name(obj, prog_name); 20 20 if (CHECK(!prog, "find_prog", "prog '%s' not found\n", prog_name)) 21 21 goto close_prog; 22 22
+2 -2
tools/testing/selftests/bpf/prog_tests/stacktrace_map_raw_tp.c
··· 3 3 4 4 void test_stacktrace_map_raw_tp(void) 5 5 { 6 - const char *prog_name = "tracepoint/sched/sched_switch"; 6 + const char *prog_name = "oncpu"; 7 7 int control_map_fd, stackid_hmap_fd, stackmap_fd; 8 8 const char *file = "./test_stacktrace_map.o"; 9 9 __u32 key, val, duration = 0; ··· 16 16 if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno)) 17 17 return; 18 18 19 - prog = bpf_object__find_program_by_title(obj, prog_name); 19 + prog = bpf_object__find_program_by_name(obj, prog_name); 20 20 if (CHECK(!prog, "find_prog", "prog '%s' not found\n", prog_name)) 21 21 goto close_prog; 22 22
+6 -14
tools/testing/selftests/bpf/prog_tests/test_local_storage.c
··· 28 28 struct storage { 29 29 void *inode; 30 30 unsigned int value; 31 - /* Lock ensures that spin locked versions of local stoage operations 32 - * also work, most operations in this tests are still single threaded 33 - */ 34 - struct bpf_spin_lock lock; 35 31 }; 36 32 37 33 /* Fork and exec the provided rm binary and return the exit code of the ··· 62 66 63 67 static bool check_syscall_operations(int map_fd, int obj_fd) 64 68 { 65 - struct storage val = { .value = TEST_STORAGE_VALUE, .lock = { 0 } }, 66 - lookup_val = { .value = 0, .lock = { 0 } }; 69 + struct storage val = { .value = TEST_STORAGE_VALUE }, 70 + lookup_val = { .value = 0 }; 67 71 int err; 68 72 69 73 /* Looking up an existing element should fail initially */ 70 - err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 71 - BPF_F_LOCK); 74 + err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 0); 72 75 if (CHECK(!err || errno != ENOENT, "bpf_map_lookup_elem", 73 76 "err:%d errno:%d\n", err, errno)) 74 77 return false; 75 78 76 79 /* Create a new element */ 77 - err = bpf_map_update_elem(map_fd, &obj_fd, &val, 78 - BPF_NOEXIST | BPF_F_LOCK); 80 + err = bpf_map_update_elem(map_fd, &obj_fd, &val, BPF_NOEXIST); 79 81 if (CHECK(err < 0, "bpf_map_update_elem", "err:%d errno:%d\n", err, 80 82 errno)) 81 83 return false; 82 84 83 85 /* Lookup the newly created element */ 84 - err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 85 - BPF_F_LOCK); 86 + err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 0); 86 87 if (CHECK(err < 0, "bpf_map_lookup_elem", "err:%d errno:%d", err, 87 88 errno)) 88 89 return false; ··· 95 102 return false; 96 103 97 104 /* The lookup should fail, now that the element has been deleted */ 98 - err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 99 - BPF_F_LOCK); 105 + err = bpf_map_lookup_elem_flags(map_fd, &obj_fd, &lookup_val, 0); 100 106 if (CHECK(!err || errno != ENOENT, "bpf_map_lookup_elem", 101 107 "err:%d errno:%d\n", err, errno)) 102 108 return false;
+10 -10
tools/testing/selftests/bpf/prog_tests/test_overhead.c
··· 56 56 57 57 void test_test_overhead(void) 58 58 { 59 - const char *kprobe_name = "kprobe/__set_task_comm"; 60 - const char *kretprobe_name = "kretprobe/__set_task_comm"; 61 - const char *raw_tp_name = "raw_tp/task_rename"; 62 - const char *fentry_name = "fentry/__set_task_comm"; 63 - const char *fexit_name = "fexit/__set_task_comm"; 59 + const char *kprobe_name = "prog1"; 60 + const char *kretprobe_name = "prog2"; 61 + const char *raw_tp_name = "prog3"; 62 + const char *fentry_name = "prog4"; 63 + const char *fexit_name = "prog5"; 64 64 const char *kprobe_func = "__set_task_comm"; 65 65 struct bpf_program *kprobe_prog, *kretprobe_prog, *raw_tp_prog; 66 66 struct bpf_program *fentry_prog, *fexit_prog; ··· 76 76 if (!ASSERT_OK_PTR(obj, "obj_open_file")) 77 77 return; 78 78 79 - kprobe_prog = bpf_object__find_program_by_title(obj, kprobe_name); 79 + kprobe_prog = bpf_object__find_program_by_name(obj, kprobe_name); 80 80 if (CHECK(!kprobe_prog, "find_probe", 81 81 "prog '%s' not found\n", kprobe_name)) 82 82 goto cleanup; 83 - kretprobe_prog = bpf_object__find_program_by_title(obj, kretprobe_name); 83 + kretprobe_prog = bpf_object__find_program_by_name(obj, kretprobe_name); 84 84 if (CHECK(!kretprobe_prog, "find_probe", 85 85 "prog '%s' not found\n", kretprobe_name)) 86 86 goto cleanup; 87 - raw_tp_prog = bpf_object__find_program_by_title(obj, raw_tp_name); 87 + raw_tp_prog = bpf_object__find_program_by_name(obj, raw_tp_name); 88 88 if (CHECK(!raw_tp_prog, "find_probe", 89 89 "prog '%s' not found\n", raw_tp_name)) 90 90 goto cleanup; 91 - fentry_prog = bpf_object__find_program_by_title(obj, fentry_name); 91 + fentry_prog = bpf_object__find_program_by_name(obj, fentry_name); 92 92 if (CHECK(!fentry_prog, "find_probe", 93 93 "prog '%s' not found\n", fentry_name)) 94 94 goto cleanup; 95 - fexit_prog = bpf_object__find_program_by_title(obj, fexit_name); 95 + fexit_prog = bpf_object__find_program_by_name(obj, fexit_name); 96 96 if (CHECK(!fexit_prog, "find_probe", 97 97 "prog '%s' not found\n", fexit_name)) 98 98 goto cleanup;
+167
tools/testing/selftests/bpf/prog_tests/test_strncmp.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (C) 2021. Huawei Technologies Co., Ltd */ 3 + #include <test_progs.h> 4 + #include "strncmp_test.skel.h" 5 + 6 + static int trigger_strncmp(const struct strncmp_test *skel) 7 + { 8 + int cmp; 9 + 10 + usleep(1); 11 + 12 + cmp = skel->bss->cmp_ret; 13 + if (cmp > 0) 14 + return 1; 15 + if (cmp < 0) 16 + return -1; 17 + return 0; 18 + } 19 + 20 + /* 21 + * Compare str and target after making str[i] != target[i]. 22 + * When exp is -1, make str[i] < target[i] and delta = -1. 23 + */ 24 + static void strncmp_full_str_cmp(struct strncmp_test *skel, const char *name, 25 + int exp) 26 + { 27 + size_t nr = sizeof(skel->bss->str); 28 + char *str = skel->bss->str; 29 + int delta = exp; 30 + int got; 31 + size_t i; 32 + 33 + memcpy(str, skel->rodata->target, nr); 34 + for (i = 0; i < nr - 1; i++) { 35 + str[i] += delta; 36 + 37 + got = trigger_strncmp(skel); 38 + ASSERT_EQ(got, exp, name); 39 + 40 + str[i] -= delta; 41 + } 42 + } 43 + 44 + static void test_strncmp_ret(void) 45 + { 46 + struct strncmp_test *skel; 47 + struct bpf_program *prog; 48 + int err, got; 49 + 50 + skel = strncmp_test__open(); 51 + if (!ASSERT_OK_PTR(skel, "strncmp_test open")) 52 + return; 53 + 54 + bpf_object__for_each_program(prog, skel->obj) 55 + bpf_program__set_autoload(prog, false); 56 + 57 + bpf_program__set_autoload(skel->progs.do_strncmp, true); 58 + 59 + err = strncmp_test__load(skel); 60 + if (!ASSERT_EQ(err, 0, "strncmp_test load")) 61 + goto out; 62 + 63 + err = strncmp_test__attach(skel); 64 + if (!ASSERT_EQ(err, 0, "strncmp_test attach")) 65 + goto out; 66 + 67 + skel->bss->target_pid = getpid(); 68 + 69 + /* Empty str */ 70 + skel->bss->str[0] = '\0'; 71 + got = trigger_strncmp(skel); 72 + ASSERT_EQ(got, -1, "strncmp: empty str"); 73 + 74 + /* Same string */ 75 + memcpy(skel->bss->str, skel->rodata->target, sizeof(skel->bss->str)); 76 + got = trigger_strncmp(skel); 77 + ASSERT_EQ(got, 0, "strncmp: same str"); 78 + 79 + /* Not-null-termainted string */ 80 + memcpy(skel->bss->str, skel->rodata->target, sizeof(skel->bss->str)); 81 + skel->bss->str[sizeof(skel->bss->str) - 1] = 'A'; 82 + got = trigger_strncmp(skel); 83 + ASSERT_EQ(got, 1, "strncmp: not-null-term str"); 84 + 85 + strncmp_full_str_cmp(skel, "strncmp: less than", -1); 86 + strncmp_full_str_cmp(skel, "strncmp: greater than", 1); 87 + out: 88 + strncmp_test__destroy(skel); 89 + } 90 + 91 + static void test_strncmp_bad_not_const_str_size(void) 92 + { 93 + struct strncmp_test *skel; 94 + struct bpf_program *prog; 95 + int err; 96 + 97 + skel = strncmp_test__open(); 98 + if (!ASSERT_OK_PTR(skel, "strncmp_test open")) 99 + return; 100 + 101 + bpf_object__for_each_program(prog, skel->obj) 102 + bpf_program__set_autoload(prog, false); 103 + 104 + bpf_program__set_autoload(skel->progs.strncmp_bad_not_const_str_size, 105 + true); 106 + 107 + err = strncmp_test__load(skel); 108 + ASSERT_ERR(err, "strncmp_test load bad_not_const_str_size"); 109 + 110 + strncmp_test__destroy(skel); 111 + } 112 + 113 + static void test_strncmp_bad_writable_target(void) 114 + { 115 + struct strncmp_test *skel; 116 + struct bpf_program *prog; 117 + int err; 118 + 119 + skel = strncmp_test__open(); 120 + if (!ASSERT_OK_PTR(skel, "strncmp_test open")) 121 + return; 122 + 123 + bpf_object__for_each_program(prog, skel->obj) 124 + bpf_program__set_autoload(prog, false); 125 + 126 + bpf_program__set_autoload(skel->progs.strncmp_bad_writable_target, 127 + true); 128 + 129 + err = strncmp_test__load(skel); 130 + ASSERT_ERR(err, "strncmp_test load bad_writable_target"); 131 + 132 + strncmp_test__destroy(skel); 133 + } 134 + 135 + static void test_strncmp_bad_not_null_term_target(void) 136 + { 137 + struct strncmp_test *skel; 138 + struct bpf_program *prog; 139 + int err; 140 + 141 + skel = strncmp_test__open(); 142 + if (!ASSERT_OK_PTR(skel, "strncmp_test open")) 143 + return; 144 + 145 + bpf_object__for_each_program(prog, skel->obj) 146 + bpf_program__set_autoload(prog, false); 147 + 148 + bpf_program__set_autoload(skel->progs.strncmp_bad_not_null_term_target, 149 + true); 150 + 151 + err = strncmp_test__load(skel); 152 + ASSERT_ERR(err, "strncmp_test load bad_not_null_term_target"); 153 + 154 + strncmp_test__destroy(skel); 155 + } 156 + 157 + void test_test_strncmp(void) 158 + { 159 + if (test__start_subtest("strncmp_ret")) 160 + test_strncmp_ret(); 161 + if (test__start_subtest("strncmp_bad_not_const_str_size")) 162 + test_strncmp_bad_not_const_str_size(); 163 + if (test__start_subtest("strncmp_bad_writable_target")) 164 + test_strncmp_bad_writable_target(); 165 + if (test__start_subtest("strncmp_bad_not_null_term_target")) 166 + test_strncmp_bad_not_null_term_target(); 167 + }
+3 -3
tools/testing/selftests/bpf/prog_tests/trampoline_count.c
··· 35 35 struct bpf_program *prog; 36 36 int duration = 0; 37 37 38 - prog = bpf_object__find_program_by_title(obj, name); 38 + prog = bpf_object__find_program_by_name(obj, name); 39 39 if (CHECK(!prog, "find_probe", "prog '%s' not found\n", name)) 40 40 return ERR_PTR(-EINVAL); 41 41 return bpf_program__attach_trace(prog); ··· 44 44 /* TODO: use different target function to run in concurrent mode */ 45 45 void serial_test_trampoline_count(void) 46 46 { 47 - const char *fentry_name = "fentry/__set_task_comm"; 48 - const char *fexit_name = "fexit/__set_task_comm"; 47 + const char *fentry_name = "prog1"; 48 + const char *fexit_name = "prog2"; 49 49 const char *object = "test_trampoline_count.o"; 50 50 struct inst inst[MAX_TRAMP_PROGS] = {}; 51 51 int err, i = 0, duration = 0;
+123
tools/testing/selftests/bpf/progs/get_func_args_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <linux/bpf.h> 3 + #include <bpf/bpf_helpers.h> 4 + #include <bpf/bpf_tracing.h> 5 + #include <errno.h> 6 + 7 + char _license[] SEC("license") = "GPL"; 8 + 9 + __u64 test1_result = 0; 10 + SEC("fentry/bpf_fentry_test1") 11 + int BPF_PROG(test1) 12 + { 13 + __u64 cnt = bpf_get_func_arg_cnt(ctx); 14 + __u64 a = 0, z = 0, ret = 0; 15 + __s64 err; 16 + 17 + test1_result = cnt == 1; 18 + 19 + /* valid arguments */ 20 + err = bpf_get_func_arg(ctx, 0, &a); 21 + 22 + /* We need to cast access to traced function argument values with 23 + * proper type cast, because trampoline uses type specific instruction 24 + * to save it, like for 'int a' with 32-bit mov like: 25 + * 26 + * mov %edi,-0x8(%rbp) 27 + * 28 + * so the upper 4 bytes are not zeroed. 29 + */ 30 + test1_result &= err == 0 && ((int) a == 1); 31 + 32 + /* not valid argument */ 33 + err = bpf_get_func_arg(ctx, 1, &z); 34 + test1_result &= err == -EINVAL; 35 + 36 + /* return value fails in fentry */ 37 + err = bpf_get_func_ret(ctx, &ret); 38 + test1_result &= err == -EOPNOTSUPP; 39 + return 0; 40 + } 41 + 42 + __u64 test2_result = 0; 43 + SEC("fexit/bpf_fentry_test2") 44 + int BPF_PROG(test2) 45 + { 46 + __u64 cnt = bpf_get_func_arg_cnt(ctx); 47 + __u64 a = 0, b = 0, z = 0, ret = 0; 48 + __s64 err; 49 + 50 + test2_result = cnt == 2; 51 + 52 + /* valid arguments */ 53 + err = bpf_get_func_arg(ctx, 0, &a); 54 + test2_result &= err == 0 && (int) a == 2; 55 + 56 + err = bpf_get_func_arg(ctx, 1, &b); 57 + test2_result &= err == 0 && b == 3; 58 + 59 + /* not valid argument */ 60 + err = bpf_get_func_arg(ctx, 2, &z); 61 + test2_result &= err == -EINVAL; 62 + 63 + /* return value */ 64 + err = bpf_get_func_ret(ctx, &ret); 65 + test2_result &= err == 0 && ret == 5; 66 + return 0; 67 + } 68 + 69 + __u64 test3_result = 0; 70 + SEC("fmod_ret/bpf_modify_return_test") 71 + int BPF_PROG(fmod_ret_test, int _a, int *_b, int _ret) 72 + { 73 + __u64 cnt = bpf_get_func_arg_cnt(ctx); 74 + __u64 a = 0, b = 0, z = 0, ret = 0; 75 + __s64 err; 76 + 77 + test3_result = cnt == 2; 78 + 79 + /* valid arguments */ 80 + err = bpf_get_func_arg(ctx, 0, &a); 81 + test3_result &= err == 0 && ((int) a == 1); 82 + 83 + err = bpf_get_func_arg(ctx, 1, &b); 84 + test3_result &= err == 0 && ((int *) b == _b); 85 + 86 + /* not valid argument */ 87 + err = bpf_get_func_arg(ctx, 2, &z); 88 + test3_result &= err == -EINVAL; 89 + 90 + /* return value */ 91 + err = bpf_get_func_ret(ctx, &ret); 92 + test3_result &= err == 0 && ret == 0; 93 + 94 + /* change return value, it's checked in fexit_test program */ 95 + return 1234; 96 + } 97 + 98 + __u64 test4_result = 0; 99 + SEC("fexit/bpf_modify_return_test") 100 + int BPF_PROG(fexit_test, int _a, int *_b, int _ret) 101 + { 102 + __u64 cnt = bpf_get_func_arg_cnt(ctx); 103 + __u64 a = 0, b = 0, z = 0, ret = 0; 104 + __s64 err; 105 + 106 + test4_result = cnt == 2; 107 + 108 + /* valid arguments */ 109 + err = bpf_get_func_arg(ctx, 0, &a); 110 + test4_result &= err == 0 && ((int) a == 1); 111 + 112 + err = bpf_get_func_arg(ctx, 1, &b); 113 + test4_result &= err == 0 && ((int *) b == _b); 114 + 115 + /* not valid argument */ 116 + err = bpf_get_func_arg(ctx, 2, &z); 117 + test4_result &= err == -EINVAL; 118 + 119 + /* return value */ 120 + err = bpf_get_func_ret(ctx, &ret); 121 + test4_result &= err == 0 && ret == 1234; 122 + return 0; 123 + }
+5 -19
tools/testing/selftests/bpf/progs/local_storage.c
··· 20 20 struct local_storage { 21 21 struct inode *exec_inode; 22 22 __u32 value; 23 - struct bpf_spin_lock lock; 24 23 }; 25 24 26 25 struct { ··· 57 58 bpf_get_current_task_btf(), 0, 0); 58 59 if (storage) { 59 60 /* Don't let an executable delete itself */ 60 - bpf_spin_lock(&storage->lock); 61 61 is_self_unlink = storage->exec_inode == victim->d_inode; 62 - bpf_spin_unlock(&storage->lock); 63 62 if (is_self_unlink) 64 63 return -EPERM; 65 64 } ··· 65 68 return 0; 66 69 } 67 70 68 - SEC("lsm/inode_rename") 71 + SEC("lsm.s/inode_rename") 69 72 int BPF_PROG(inode_rename, struct inode *old_dir, struct dentry *old_dentry, 70 73 struct inode *new_dir, struct dentry *new_dentry, 71 74 unsigned int flags) ··· 86 89 if (!storage) 87 90 return 0; 88 91 89 - bpf_spin_lock(&storage->lock); 90 92 if (storage->value != DUMMY_STORAGE_VALUE) 91 93 inode_storage_result = -1; 92 - bpf_spin_unlock(&storage->lock); 93 94 94 95 err = bpf_inode_storage_delete(&inode_storage_map, old_dentry->d_inode); 95 96 if (!err) ··· 96 101 return 0; 97 102 } 98 103 99 - SEC("lsm/socket_bind") 104 + SEC("lsm.s/socket_bind") 100 105 int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address, 101 106 int addrlen) 102 107 { ··· 112 117 if (!storage) 113 118 return 0; 114 119 115 - bpf_spin_lock(&storage->lock); 116 120 if (storage->value != DUMMY_STORAGE_VALUE) 117 121 sk_storage_result = -1; 118 - bpf_spin_unlock(&storage->lock); 119 122 120 123 err = bpf_sk_storage_delete(&sk_storage_map, sock->sk); 121 124 if (!err) ··· 122 129 return 0; 123 130 } 124 131 125 - SEC("lsm/socket_post_create") 132 + SEC("lsm.s/socket_post_create") 126 133 int BPF_PROG(socket_post_create, struct socket *sock, int family, int type, 127 134 int protocol, int kern) 128 135 { ··· 137 144 if (!storage) 138 145 return 0; 139 146 140 - bpf_spin_lock(&storage->lock); 141 147 storage->value = DUMMY_STORAGE_VALUE; 142 - bpf_spin_unlock(&storage->lock); 143 148 144 149 return 0; 145 150 } ··· 145 154 /* This uses the local storage to remember the inode of the binary that a 146 155 * process was originally executing. 147 156 */ 148 - SEC("lsm/bprm_committed_creds") 157 + SEC("lsm.s/bprm_committed_creds") 149 158 void BPF_PROG(exec, struct linux_binprm *bprm) 150 159 { 151 160 __u32 pid = bpf_get_current_pid_tgid() >> 32; ··· 157 166 storage = bpf_task_storage_get(&task_storage_map, 158 167 bpf_get_current_task_btf(), 0, 159 168 BPF_LOCAL_STORAGE_GET_F_CREATE); 160 - if (storage) { 161 - bpf_spin_lock(&storage->lock); 169 + if (storage) 162 170 storage->exec_inode = bprm->file->f_inode; 163 - bpf_spin_unlock(&storage->lock); 164 - } 165 171 166 172 storage = bpf_inode_storage_get(&inode_storage_map, bprm->file->f_inode, 167 173 0, BPF_LOCAL_STORAGE_GET_F_CREATE); 168 174 if (!storage) 169 175 return; 170 176 171 - bpf_spin_lock(&storage->lock); 172 177 storage->value = DUMMY_STORAGE_VALUE; 173 - bpf_spin_unlock(&storage->lock); 174 178 }
+50
tools/testing/selftests/bpf/progs/strncmp_bench.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (C) 2021. Huawei Technologies Co., Ltd */ 3 + #include <linux/types.h> 4 + #include <linux/bpf.h> 5 + #include <bpf/bpf_helpers.h> 6 + #include <bpf/bpf_tracing.h> 7 + 8 + #define STRNCMP_STR_SZ 4096 9 + 10 + /* Will be updated by benchmark before program loading */ 11 + const volatile unsigned int cmp_str_len = 1; 12 + const char target[STRNCMP_STR_SZ]; 13 + 14 + long hits = 0; 15 + char str[STRNCMP_STR_SZ]; 16 + 17 + char _license[] SEC("license") = "GPL"; 18 + 19 + static __always_inline int local_strncmp(const char *s1, unsigned int sz, 20 + const char *s2) 21 + { 22 + int ret = 0; 23 + unsigned int i; 24 + 25 + for (i = 0; i < sz; i++) { 26 + /* E.g. 0xff > 0x31 */ 27 + ret = (unsigned char)s1[i] - (unsigned char)s2[i]; 28 + if (ret || !s1[i]) 29 + break; 30 + } 31 + 32 + return ret; 33 + } 34 + 35 + SEC("tp/syscalls/sys_enter_getpgid") 36 + int strncmp_no_helper(void *ctx) 37 + { 38 + if (local_strncmp(str, cmp_str_len + 1, target) < 0) 39 + __sync_add_and_fetch(&hits, 1); 40 + return 0; 41 + } 42 + 43 + SEC("tp/syscalls/sys_enter_getpgid") 44 + int strncmp_helper(void *ctx) 45 + { 46 + if (bpf_strncmp(str, cmp_str_len + 1, target) < 0) 47 + __sync_add_and_fetch(&hits, 1); 48 + return 0; 49 + } 50 +
+54
tools/testing/selftests/bpf/progs/strncmp_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (C) 2021. Huawei Technologies Co., Ltd */ 3 + #include <stdbool.h> 4 + #include <linux/types.h> 5 + #include <linux/bpf.h> 6 + #include <bpf/bpf_helpers.h> 7 + #include <bpf/bpf_tracing.h> 8 + 9 + #define STRNCMP_STR_SZ 8 10 + 11 + const char target[STRNCMP_STR_SZ] = "EEEEEEE"; 12 + char str[STRNCMP_STR_SZ]; 13 + int cmp_ret = 0; 14 + int target_pid = 0; 15 + 16 + const char no_str_target[STRNCMP_STR_SZ] = "12345678"; 17 + char writable_target[STRNCMP_STR_SZ]; 18 + unsigned int no_const_str_size = STRNCMP_STR_SZ; 19 + 20 + char _license[] SEC("license") = "GPL"; 21 + 22 + SEC("tp/syscalls/sys_enter_nanosleep") 23 + int do_strncmp(void *ctx) 24 + { 25 + if ((bpf_get_current_pid_tgid() >> 32) != target_pid) 26 + return 0; 27 + 28 + cmp_ret = bpf_strncmp(str, STRNCMP_STR_SZ, target); 29 + return 0; 30 + } 31 + 32 + SEC("tp/syscalls/sys_enter_nanosleep") 33 + int strncmp_bad_not_const_str_size(void *ctx) 34 + { 35 + /* The value of string size is not const, so will fail */ 36 + cmp_ret = bpf_strncmp(str, no_const_str_size, target); 37 + return 0; 38 + } 39 + 40 + SEC("tp/syscalls/sys_enter_nanosleep") 41 + int strncmp_bad_writable_target(void *ctx) 42 + { 43 + /* Compared target is not read-only, so will fail */ 44 + cmp_ret = bpf_strncmp(str, STRNCMP_STR_SZ, writable_target); 45 + return 0; 46 + } 47 + 48 + SEC("tp/syscalls/sys_enter_nanosleep") 49 + int strncmp_bad_not_null_term_target(void *ctx) 50 + { 51 + /* Compared target is not null-terminated, so will fail */ 52 + cmp_ret = bpf_strncmp(str, STRNCMP_STR_SZ, no_str_target); 53 + return 0; 54 + }
+29
tools/testing/selftests/bpf/progs/test_ksyms_btf_write_check.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (c) 2021 Google */ 3 + 4 + #include "vmlinux.h" 5 + 6 + #include <bpf/bpf_helpers.h> 7 + 8 + extern const int bpf_prog_active __ksym; /* int type global var. */ 9 + 10 + SEC("raw_tp/sys_enter") 11 + int handler(const void *ctx) 12 + { 13 + int *active; 14 + __u32 cpu; 15 + 16 + cpu = bpf_get_smp_processor_id(); 17 + active = (int *)bpf_per_cpu_ptr(&bpf_prog_active, cpu); 18 + if (active) { 19 + /* Kernel memory obtained from bpf_{per,this}_cpu_ptr 20 + * is read-only, should _not_ pass verification. 21 + */ 22 + /* WRITE_ONCE */ 23 + *(volatile int *)active = -1; 24 + } 25 + 26 + return 0; 27 + } 28 + 29 + char _license[] SEC("license") = "GPL";
+8 -1
tools/testing/selftests/bpf/test_cpp.cpp
··· 7 7 8 8 /* do nothing, just make sure we can link successfully */ 9 9 10 + static void dump_printf(void *ctx, const char *fmt, va_list args) 11 + { 12 + } 13 + 10 14 int main(int argc, char *argv[]) 11 15 { 16 + struct btf_dump_opts opts = { }; 12 17 struct test_core_extern *skel; 18 + struct btf *btf; 13 19 14 20 /* libbpf.h */ 15 21 libbpf_set_print(NULL); ··· 24 18 bpf_prog_get_fd_by_id(0); 25 19 26 20 /* btf.h */ 27 - btf__new(NULL, 0); 21 + btf = btf__new(NULL, 0); 22 + btf_dump__new(btf, dump_printf, nullptr, &opts); 28 23 29 24 /* BPF skeleton */ 30 25 skel = test_core_extern__open_and_load();
-1
tools/testing/selftests/bpf/test_maps.c
··· 23 23 #include <bpf/libbpf.h> 24 24 25 25 #include "bpf_util.h" 26 - #include "bpf_rlimit.h" 27 26 #include "test_maps.h" 28 27 #include "testing_helpers.h" 29 28
-2
tools/testing/selftests/bpf/test_progs.c
··· 4 4 #define _GNU_SOURCE 5 5 #include "test_progs.h" 6 6 #include "cgroup_helpers.h" 7 - #include "bpf_rlimit.h" 8 7 #include <argp.h> 9 8 #include <pthread.h> 10 9 #include <sched.h> ··· 1341 1342 1342 1343 /* Use libbpf 1.0 API mode */ 1343 1344 libbpf_set_strict_mode(LIBBPF_STRICT_ALL); 1344 - 1345 1345 libbpf_set_print(libbpf_print_fn); 1346 1346 1347 1347 srand(time(NULL));
+8 -10
tools/testing/selftests/bpf/test_verifier.c
··· 41 41 # define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 1 42 42 # endif 43 43 #endif 44 - #include "bpf_rlimit.h" 45 44 #include "bpf_rand.h" 46 45 #include "bpf_util.h" 47 46 #include "test_btf.h" ··· 700 701 701 702 static int create_map_timer(void) 702 703 { 703 - struct bpf_create_map_attr attr = { 704 - .name = "test_map", 705 - .map_type = BPF_MAP_TYPE_ARRAY, 706 - .key_size = 4, 707 - .value_size = 16, 708 - .max_entries = 1, 704 + LIBBPF_OPTS(bpf_map_create_opts, opts, 709 705 .btf_key_type_id = 1, 710 706 .btf_value_type_id = 5, 711 - }; 707 + ); 712 708 int fd, btf_fd; 713 709 714 710 btf_fd = load_btf(); 715 711 if (btf_fd < 0) 716 712 return -1; 717 - attr.btf_fd = btf_fd; 718 - fd = bpf_create_map_xattr(&attr); 713 + 714 + opts.btf_fd = btf_fd; 715 + fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "test_map", 4, 16, 1, &opts); 719 716 if (fd < 0) 720 717 printf("Failed to create map with timer\n"); 721 718 return fd; ··· 1393 1398 UNPRIV_SYSCTL); 1394 1399 return EXIT_FAILURE; 1395 1400 } 1401 + 1402 + /* Use libbpf 1.0 API mode */ 1403 + libbpf_set_strict_mode(LIBBPF_STRICT_ALL); 1396 1404 1397 1405 bpf_semi_rand_init(); 1398 1406 return do_test(unpriv, from, to);
+12
tools/testing/selftests/bpf/verifier/btf_ctx_access.c
··· 1 + { 2 + "btf_ctx_access accept", 3 + .insns = { 4 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 8), /* load 2nd argument value (int pointer) */ 5 + BPF_MOV64_IMM(BPF_REG_0, 0), 6 + BPF_EXIT_INSN(), 7 + }, 8 + .result = ACCEPT, 9 + .prog_type = BPF_PROG_TYPE_TRACING, 10 + .expected_attach_type = BPF_TRACE_FENTRY, 11 + .kfunc = "bpf_modify_return_test", 12 + },
+1 -1
tools/testing/selftests/bpf/vmtest.sh
··· 32 32 OUTPUT_DIR="$HOME/.bpf_selftests" 33 33 KCONFIG_URL="https://raw.githubusercontent.com/libbpf/libbpf/master/travis-ci/vmtest/configs/config-latest.${ARCH}" 34 34 KCONFIG_API_URL="https://api.github.com/repos/libbpf/libbpf/contents/travis-ci/vmtest/configs/config-latest.${ARCH}" 35 - INDEX_URL="https://raw.githubusercontent.com/libbpf/libbpf/master/travis-ci/vmtest/configs/INDEX" 35 + INDEX_URL="https://raw.githubusercontent.com/libbpf/ci/master/INDEX" 36 36 NUM_COMPILE_JOBS="$(nproc)" 37 37 LOG_FILE_BASE="$(date +"bpf_selftests.%Y-%m-%d_%H-%M-%S")" 38 38 LOG_FILE="${LOG_FILE_BASE}.log"