Back to home page

OSCL-LXR

 
 

    


0001 {
0002     "reference tracking: leak potential reference",
0003     .insns = {
0004     BPF_SK_LOOKUP(sk_lookup_tcp),
0005     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), /* leak reference */
0006     BPF_EXIT_INSN(),
0007     },
0008     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0009     .errstr = "Unreleased reference",
0010     .result = REJECT,
0011 },
0012 {
0013     "reference tracking: leak potential reference to sock_common",
0014     .insns = {
0015     BPF_SK_LOOKUP(skc_lookup_tcp),
0016     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), /* leak reference */
0017     BPF_EXIT_INSN(),
0018     },
0019     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0020     .errstr = "Unreleased reference",
0021     .result = REJECT,
0022 },
0023 {
0024     "reference tracking: leak potential reference on stack",
0025     .insns = {
0026     BPF_SK_LOOKUP(sk_lookup_tcp),
0027     BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
0028     BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
0029     BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_0, 0),
0030     BPF_MOV64_IMM(BPF_REG_0, 0),
0031     BPF_EXIT_INSN(),
0032     },
0033     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0034     .errstr = "Unreleased reference",
0035     .result = REJECT,
0036 },
0037 {
0038     "reference tracking: leak potential reference on stack 2",
0039     .insns = {
0040     BPF_SK_LOOKUP(sk_lookup_tcp),
0041     BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
0042     BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
0043     BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_0, 0),
0044     BPF_MOV64_IMM(BPF_REG_0, 0),
0045     BPF_ST_MEM(BPF_DW, BPF_REG_4, 0, 0),
0046     BPF_EXIT_INSN(),
0047     },
0048     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0049     .errstr = "Unreleased reference",
0050     .result = REJECT,
0051 },
0052 {
0053     "reference tracking: zero potential reference",
0054     .insns = {
0055     BPF_SK_LOOKUP(sk_lookup_tcp),
0056     BPF_MOV64_IMM(BPF_REG_0, 0), /* leak reference */
0057     BPF_EXIT_INSN(),
0058     },
0059     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0060     .errstr = "Unreleased reference",
0061     .result = REJECT,
0062 },
0063 {
0064     "reference tracking: zero potential reference to sock_common",
0065     .insns = {
0066     BPF_SK_LOOKUP(skc_lookup_tcp),
0067     BPF_MOV64_IMM(BPF_REG_0, 0), /* leak reference */
0068     BPF_EXIT_INSN(),
0069     },
0070     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0071     .errstr = "Unreleased reference",
0072     .result = REJECT,
0073 },
0074 {
0075     "reference tracking: copy and zero potential references",
0076     .insns = {
0077     BPF_SK_LOOKUP(sk_lookup_tcp),
0078     BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
0079     BPF_MOV64_IMM(BPF_REG_0, 0),
0080     BPF_MOV64_IMM(BPF_REG_7, 0), /* leak reference */
0081     BPF_EXIT_INSN(),
0082     },
0083     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0084     .errstr = "Unreleased reference",
0085     .result = REJECT,
0086 },
0087 {
0088     "reference tracking: release reference without check",
0089     .insns = {
0090     BPF_SK_LOOKUP(sk_lookup_tcp),
0091     /* reference in r0 may be NULL */
0092     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0093     BPF_MOV64_IMM(BPF_REG_2, 0),
0094     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0095     BPF_EXIT_INSN(),
0096     },
0097     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0098     .errstr = "type=sock_or_null expected=sock",
0099     .result = REJECT,
0100 },
0101 {
0102     "reference tracking: release reference to sock_common without check",
0103     .insns = {
0104     BPF_SK_LOOKUP(skc_lookup_tcp),
0105     /* reference in r0 may be NULL */
0106     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0107     BPF_MOV64_IMM(BPF_REG_2, 0),
0108     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0109     BPF_EXIT_INSN(),
0110     },
0111     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0112     .errstr = "type=sock_common_or_null expected=sock",
0113     .result = REJECT,
0114 },
0115 {
0116     "reference tracking: release reference",
0117     .insns = {
0118     BPF_SK_LOOKUP(sk_lookup_tcp),
0119     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0120     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0121     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0122     BPF_EXIT_INSN(),
0123     },
0124     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0125     .result = ACCEPT,
0126 },
0127 {
0128     "reference tracking: release reference to sock_common",
0129     .insns = {
0130     BPF_SK_LOOKUP(skc_lookup_tcp),
0131     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0132     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0133     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0134     BPF_EXIT_INSN(),
0135     },
0136     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0137     .result = ACCEPT,
0138 },
0139 {
0140     "reference tracking: release reference 2",
0141     .insns = {
0142     BPF_SK_LOOKUP(sk_lookup_tcp),
0143     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0144     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0145     BPF_EXIT_INSN(),
0146     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0147     BPF_EXIT_INSN(),
0148     },
0149     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0150     .result = ACCEPT,
0151 },
0152 {
0153     "reference tracking: release reference twice",
0154     .insns = {
0155     BPF_SK_LOOKUP(sk_lookup_tcp),
0156     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0157     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0158     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0159     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0160     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0161     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0162     BPF_EXIT_INSN(),
0163     },
0164     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0165     .errstr = "type=scalar expected=sock",
0166     .result = REJECT,
0167 },
0168 {
0169     "reference tracking: release reference twice inside branch",
0170     .insns = {
0171     BPF_SK_LOOKUP(sk_lookup_tcp),
0172     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0173     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0174     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), /* goto end */
0175     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0176     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0177     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0178     BPF_EXIT_INSN(),
0179     },
0180     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0181     .errstr = "type=scalar expected=sock",
0182     .result = REJECT,
0183 },
0184 {
0185     "reference tracking: alloc, check, free in one subbranch",
0186     .insns = {
0187     BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
0188             offsetof(struct __sk_buff, data)),
0189     BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
0190             offsetof(struct __sk_buff, data_end)),
0191     BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
0192     BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 16),
0193     /* if (offsetof(skb, mark) > data_len) exit; */
0194     BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
0195     BPF_EXIT_INSN(),
0196     BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_2,
0197             offsetof(struct __sk_buff, mark)),
0198     BPF_SK_LOOKUP(sk_lookup_tcp),
0199     BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 1), /* mark == 0? */
0200     /* Leak reference in R0 */
0201     BPF_EXIT_INSN(),
0202     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), /* sk NULL? */
0203     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0204     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0205     BPF_EXIT_INSN(),
0206     },
0207     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0208     .errstr = "Unreleased reference",
0209     .result = REJECT,
0210     .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0211 },
0212 {
0213     "reference tracking: alloc, check, free in both subbranches",
0214     .insns = {
0215     BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
0216             offsetof(struct __sk_buff, data)),
0217     BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
0218             offsetof(struct __sk_buff, data_end)),
0219     BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
0220     BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 16),
0221     /* if (offsetof(skb, mark) > data_len) exit; */
0222     BPF_JMP_REG(BPF_JLE, BPF_REG_0, BPF_REG_3, 1),
0223     BPF_EXIT_INSN(),
0224     BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_2,
0225             offsetof(struct __sk_buff, mark)),
0226     BPF_SK_LOOKUP(sk_lookup_tcp),
0227     BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 4), /* mark == 0? */
0228     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), /* sk NULL? */
0229     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0230     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0231     BPF_EXIT_INSN(),
0232     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), /* sk NULL? */
0233     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0234     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0235     BPF_EXIT_INSN(),
0236     },
0237     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0238     .result = ACCEPT,
0239     .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0240 },
0241 {
0242     "reference tracking in call: free reference in subprog",
0243     .insns = {
0244     BPF_SK_LOOKUP(sk_lookup_tcp),
0245     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), /* unchecked reference */
0246     BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
0247     BPF_MOV64_IMM(BPF_REG_0, 0),
0248     BPF_EXIT_INSN(),
0249 
0250     /* subprog 1 */
0251     BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
0252     BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 1),
0253     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0254     BPF_EXIT_INSN(),
0255     },
0256     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0257     .result = ACCEPT,
0258 },
0259 {
0260     "reference tracking in call: free reference in subprog and outside",
0261     .insns = {
0262     BPF_SK_LOOKUP(sk_lookup_tcp),
0263     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), /* unchecked reference */
0264     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0265     BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
0266     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0267     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0268     BPF_EXIT_INSN(),
0269 
0270     /* subprog 1 */
0271     BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
0272     BPF_JMP_IMM(BPF_JEQ, BPF_REG_2, 0, 1),
0273     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0274     BPF_EXIT_INSN(),
0275     },
0276     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0277     .errstr = "type=scalar expected=sock",
0278     .result = REJECT,
0279 },
0280 {
0281     "reference tracking in call: alloc & leak reference in subprog",
0282     .insns = {
0283     BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
0284     BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
0285     BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3),
0286     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0287     BPF_MOV64_IMM(BPF_REG_0, 0),
0288     BPF_EXIT_INSN(),
0289 
0290     /* subprog 1 */
0291     BPF_MOV64_REG(BPF_REG_6, BPF_REG_4),
0292     BPF_SK_LOOKUP(sk_lookup_tcp),
0293     /* spill unchecked sk_ptr into stack of caller */
0294     BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_0, 0),
0295     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0296     BPF_EXIT_INSN(),
0297     },
0298     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0299     .errstr = "Unreleased reference",
0300     .result = REJECT,
0301 },
0302 {
0303     "reference tracking in call: alloc in subprog, release outside",
0304     .insns = {
0305     BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
0306     BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
0307     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0308     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0309     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0310     BPF_EXIT_INSN(),
0311 
0312     /* subprog 1 */
0313     BPF_SK_LOOKUP(sk_lookup_tcp),
0314     BPF_EXIT_INSN(), /* return sk */
0315     },
0316     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0317     .retval = POINTER_VALUE,
0318     .result = ACCEPT,
0319 },
0320 {
0321     "reference tracking in call: sk_ptr leak into caller stack",
0322     .insns = {
0323     BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
0324     BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
0325     BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
0326     BPF_MOV64_IMM(BPF_REG_0, 0),
0327     BPF_EXIT_INSN(),
0328 
0329     /* subprog 1 */
0330     BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
0331     BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, -8),
0332     BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
0333     BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
0334     /* spill unchecked sk_ptr into stack of caller */
0335     BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
0336     BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, -8),
0337     BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
0338     BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_0, 0),
0339     BPF_EXIT_INSN(),
0340 
0341     /* subprog 2 */
0342     BPF_SK_LOOKUP(sk_lookup_tcp),
0343     BPF_EXIT_INSN(),
0344     },
0345     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0346     .errstr = "Unreleased reference",
0347     .result = REJECT,
0348 },
0349 {
0350     "reference tracking in call: sk_ptr spill into caller stack",
0351     .insns = {
0352     BPF_MOV64_REG(BPF_REG_4, BPF_REG_10),
0353     BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, -8),
0354     BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 2),
0355     BPF_MOV64_IMM(BPF_REG_0, 0),
0356     BPF_EXIT_INSN(),
0357 
0358     /* subprog 1 */
0359     BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
0360     BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, -8),
0361     BPF_STX_MEM(BPF_DW, BPF_REG_5, BPF_REG_4, 0),
0362     BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 8),
0363     /* spill unchecked sk_ptr into stack of caller */
0364     BPF_MOV64_REG(BPF_REG_5, BPF_REG_10),
0365     BPF_ALU64_IMM(BPF_ADD, BPF_REG_5, -8),
0366     BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_5, 0),
0367     BPF_STX_MEM(BPF_DW, BPF_REG_4, BPF_REG_0, 0),
0368     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
0369     /* now the sk_ptr is verified, free the reference */
0370     BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_4, 0),
0371     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0372     BPF_EXIT_INSN(),
0373 
0374     /* subprog 2 */
0375     BPF_SK_LOOKUP(sk_lookup_tcp),
0376     BPF_EXIT_INSN(),
0377     },
0378     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0379     .result = ACCEPT,
0380 },
0381 {
0382     "reference tracking: allow LD_ABS",
0383     .insns = {
0384     BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
0385     BPF_SK_LOOKUP(sk_lookup_tcp),
0386     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0387     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0388     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0389     BPF_LD_ABS(BPF_B, 0),
0390     BPF_LD_ABS(BPF_H, 0),
0391     BPF_LD_ABS(BPF_W, 0),
0392     BPF_EXIT_INSN(),
0393     },
0394     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0395     .result = ACCEPT,
0396 },
0397 {
0398     "reference tracking: forbid LD_ABS while holding reference",
0399     .insns = {
0400     BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
0401     BPF_SK_LOOKUP(sk_lookup_tcp),
0402     BPF_LD_ABS(BPF_B, 0),
0403     BPF_LD_ABS(BPF_H, 0),
0404     BPF_LD_ABS(BPF_W, 0),
0405     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0406     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0407     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0408     BPF_EXIT_INSN(),
0409     },
0410     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0411     .errstr = "BPF_LD_[ABS|IND] cannot be mixed with socket references",
0412     .result = REJECT,
0413 },
0414 {
0415     "reference tracking: allow LD_IND",
0416     .insns = {
0417     BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
0418     BPF_SK_LOOKUP(sk_lookup_tcp),
0419     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0420     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0421     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0422     BPF_MOV64_IMM(BPF_REG_7, 1),
0423     BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
0424     BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
0425     BPF_EXIT_INSN(),
0426     },
0427     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0428     .result = ACCEPT,
0429     .retval = 1,
0430 },
0431 {
0432     "reference tracking: forbid LD_IND while holding reference",
0433     .insns = {
0434     BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
0435     BPF_SK_LOOKUP(sk_lookup_tcp),
0436     BPF_MOV64_REG(BPF_REG_4, BPF_REG_0),
0437     BPF_MOV64_IMM(BPF_REG_7, 1),
0438     BPF_LD_IND(BPF_W, BPF_REG_7, -0x200000),
0439     BPF_MOV64_REG(BPF_REG_0, BPF_REG_7),
0440     BPF_MOV64_REG(BPF_REG_1, BPF_REG_4),
0441     BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
0442     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0443     BPF_EXIT_INSN(),
0444     },
0445     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0446     .errstr = "BPF_LD_[ABS|IND] cannot be mixed with socket references",
0447     .result = REJECT,
0448 },
0449 {
0450     "reference tracking: check reference or tail call",
0451     .insns = {
0452     BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
0453     BPF_SK_LOOKUP(sk_lookup_tcp),
0454     /* if (sk) bpf_sk_release() */
0455     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0456     BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 7),
0457     /* bpf_tail_call() */
0458     BPF_MOV64_IMM(BPF_REG_3, 3),
0459     BPF_LD_MAP_FD(BPF_REG_2, 0),
0460     BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
0461     BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0462     BPF_MOV64_IMM(BPF_REG_0, 0),
0463     BPF_EXIT_INSN(),
0464     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0465     BPF_EXIT_INSN(),
0466     },
0467     .fixup_prog1 = { 17 },
0468     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0469     .result = ACCEPT,
0470 },
0471 {
0472     "reference tracking: release reference then tail call",
0473     .insns = {
0474     BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
0475     BPF_SK_LOOKUP(sk_lookup_tcp),
0476     /* if (sk) bpf_sk_release() */
0477     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0478     BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
0479     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0480     /* bpf_tail_call() */
0481     BPF_MOV64_IMM(BPF_REG_3, 3),
0482     BPF_LD_MAP_FD(BPF_REG_2, 0),
0483     BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
0484     BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0485     BPF_MOV64_IMM(BPF_REG_0, 0),
0486     BPF_EXIT_INSN(),
0487     },
0488     .fixup_prog1 = { 18 },
0489     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0490     .result = ACCEPT,
0491 },
0492 {
0493     "reference tracking: leak possible reference over tail call",
0494     .insns = {
0495     BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
0496     /* Look up socket and store in REG_6 */
0497     BPF_SK_LOOKUP(sk_lookup_tcp),
0498     /* bpf_tail_call() */
0499     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0500     BPF_MOV64_IMM(BPF_REG_3, 3),
0501     BPF_LD_MAP_FD(BPF_REG_2, 0),
0502     BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
0503     BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0504     BPF_MOV64_IMM(BPF_REG_0, 0),
0505     /* if (sk) bpf_sk_release() */
0506     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0507     BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
0508     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0509     BPF_EXIT_INSN(),
0510     },
0511     .fixup_prog1 = { 16 },
0512     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0513     .errstr = "tail_call would lead to reference leak",
0514     .result = REJECT,
0515 },
0516 {
0517     "reference tracking: leak checked reference over tail call",
0518     .insns = {
0519     BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
0520     /* Look up socket and store in REG_6 */
0521     BPF_SK_LOOKUP(sk_lookup_tcp),
0522     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0523     /* if (!sk) goto end */
0524     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
0525     /* bpf_tail_call() */
0526     BPF_MOV64_IMM(BPF_REG_3, 0),
0527     BPF_LD_MAP_FD(BPF_REG_2, 0),
0528     BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
0529     BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0530     BPF_MOV64_IMM(BPF_REG_0, 0),
0531     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0532     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0533     BPF_EXIT_INSN(),
0534     },
0535     .fixup_prog1 = { 17 },
0536     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0537     .errstr = "tail_call would lead to reference leak",
0538     .result = REJECT,
0539 },
0540 {
0541     "reference tracking: mangle and release sock_or_null",
0542     .insns = {
0543     BPF_SK_LOOKUP(sk_lookup_tcp),
0544     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0545     BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 5),
0546     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0547     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0548     BPF_EXIT_INSN(),
0549     },
0550     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0551     .errstr = "R1 pointer arithmetic on sock_or_null prohibited",
0552     .result = REJECT,
0553 },
0554 {
0555     "reference tracking: mangle and release sock",
0556     .insns = {
0557     BPF_SK_LOOKUP(sk_lookup_tcp),
0558     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0559     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
0560     BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 5),
0561     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0562     BPF_EXIT_INSN(),
0563     },
0564     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0565     .errstr = "R1 pointer arithmetic on sock prohibited",
0566     .result = REJECT,
0567 },
0568 {
0569     "reference tracking: access member",
0570     .insns = {
0571     BPF_SK_LOOKUP(sk_lookup_tcp),
0572     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0573     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
0574     BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_0, 4),
0575     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0576     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0577     BPF_EXIT_INSN(),
0578     },
0579     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0580     .result = ACCEPT,
0581 },
0582 {
0583     "reference tracking: write to member",
0584     .insns = {
0585     BPF_SK_LOOKUP(sk_lookup_tcp),
0586     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0587     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
0588     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0589     BPF_LD_IMM64(BPF_REG_2, 42),
0590     BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_2,
0591             offsetof(struct bpf_sock, mark)),
0592     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0593     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0594     BPF_LD_IMM64(BPF_REG_0, 0),
0595     BPF_EXIT_INSN(),
0596     },
0597     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0598     .errstr = "cannot write into sock",
0599     .result = REJECT,
0600 },
0601 {
0602     "reference tracking: invalid 64-bit access of member",
0603     .insns = {
0604     BPF_SK_LOOKUP(sk_lookup_tcp),
0605     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0606     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
0607     BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 0),
0608     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0609     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0610     BPF_EXIT_INSN(),
0611     },
0612     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0613     .errstr = "invalid sock access off=0 size=8",
0614     .result = REJECT,
0615 },
0616 {
0617     "reference tracking: access after release",
0618     .insns = {
0619     BPF_SK_LOOKUP(sk_lookup_tcp),
0620     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0621     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
0622     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0623     BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
0624     BPF_EXIT_INSN(),
0625     },
0626     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0627     .errstr = "!read_ok",
0628     .result = REJECT,
0629 },
0630 {
0631     "reference tracking: direct access for lookup",
0632     .insns = {
0633     /* Check that the packet is at least 64B long */
0634     BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
0635             offsetof(struct __sk_buff, data)),
0636     BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
0637             offsetof(struct __sk_buff, data_end)),
0638     BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
0639     BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 64),
0640     BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 9),
0641     /* sk = sk_lookup_tcp(ctx, skb->data, ...) */
0642     BPF_MOV64_IMM(BPF_REG_3, sizeof(struct bpf_sock_tuple)),
0643     BPF_MOV64_IMM(BPF_REG_4, 0),
0644     BPF_MOV64_IMM(BPF_REG_5, 0),
0645     BPF_EMIT_CALL(BPF_FUNC_sk_lookup_tcp),
0646     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0647     BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3),
0648     BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_0, 4),
0649     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0650     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0651     BPF_EXIT_INSN(),
0652     },
0653     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0654     .result = ACCEPT,
0655 },
0656 {
0657     "reference tracking: use ptr from bpf_tcp_sock() after release",
0658     .insns = {
0659     BPF_SK_LOOKUP(sk_lookup_tcp),
0660     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0661     BPF_EXIT_INSN(),
0662     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0663     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0664     BPF_EMIT_CALL(BPF_FUNC_tcp_sock),
0665     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
0666     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0667     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0668     BPF_EXIT_INSN(),
0669     BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
0670     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0671     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0672     BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_7, offsetof(struct bpf_tcp_sock, snd_cwnd)),
0673     BPF_EXIT_INSN(),
0674     },
0675     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0676     .result = REJECT,
0677     .errstr = "invalid mem access",
0678     .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0679 },
0680 {
0681     "reference tracking: use ptr from bpf_sk_fullsock() after release",
0682     .insns = {
0683     BPF_SK_LOOKUP(sk_lookup_tcp),
0684     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0685     BPF_EXIT_INSN(),
0686     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0687     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0688     BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
0689     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
0690     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0691     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0692     BPF_EXIT_INSN(),
0693     BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
0694     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0695     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0696     BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_7, offsetof(struct bpf_sock, type)),
0697     BPF_EXIT_INSN(),
0698     },
0699     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0700     .result = REJECT,
0701     .errstr = "invalid mem access",
0702     .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0703 },
0704 {
0705     "reference tracking: use ptr from bpf_sk_fullsock(tp) after release",
0706     .insns = {
0707     BPF_SK_LOOKUP(sk_lookup_tcp),
0708     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0709     BPF_EXIT_INSN(),
0710     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0711     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0712     BPF_EMIT_CALL(BPF_FUNC_tcp_sock),
0713     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
0714     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0715     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0716     BPF_EXIT_INSN(),
0717     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0718     BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
0719     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0720     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0721     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0722     BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 1),
0723     BPF_EXIT_INSN(),
0724     BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, type)),
0725     BPF_EXIT_INSN(),
0726     },
0727     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0728     .result = REJECT,
0729     .errstr = "invalid mem access",
0730     .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0731 },
0732 {
0733     "reference tracking: use sk after bpf_sk_release(tp)",
0734     .insns = {
0735     BPF_SK_LOOKUP(sk_lookup_tcp),
0736     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0737     BPF_EXIT_INSN(),
0738     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0739     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0740     BPF_EMIT_CALL(BPF_FUNC_tcp_sock),
0741     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
0742     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0743     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0744     BPF_EXIT_INSN(),
0745     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0746     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0747     BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, type)),
0748     BPF_EXIT_INSN(),
0749     },
0750     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0751     .result = REJECT,
0752     .errstr = "invalid mem access",
0753     .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0754 },
0755 {
0756     "reference tracking: use ptr from bpf_get_listener_sock() after bpf_sk_release(sk)",
0757     .insns = {
0758     BPF_SK_LOOKUP(sk_lookup_tcp),
0759     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0760     BPF_EXIT_INSN(),
0761     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0762     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0763     BPF_EMIT_CALL(BPF_FUNC_get_listener_sock),
0764     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
0765     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0766     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0767     BPF_EXIT_INSN(),
0768     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0769     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0770     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0771     BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, src_port)),
0772     BPF_EXIT_INSN(),
0773     },
0774     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0775     .result = ACCEPT,
0776 },
0777 {
0778     "reference tracking: bpf_sk_release(listen_sk)",
0779     .insns = {
0780     BPF_SK_LOOKUP(sk_lookup_tcp),
0781     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0782     BPF_EXIT_INSN(),
0783     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0784     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0785     BPF_EMIT_CALL(BPF_FUNC_get_listener_sock),
0786     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
0787     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0788     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0789     BPF_EXIT_INSN(),
0790     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0791     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0792     BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, offsetof(struct bpf_sock, type)),
0793     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0794     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0795     BPF_EXIT_INSN(),
0796     },
0797     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0798     .result = REJECT,
0799     .errstr = "R1 must be referenced when passed to release function",
0800 },
0801 {
0802     /* !bpf_sk_fullsock(sk) is checked but !bpf_tcp_sock(sk) is not checked */
0803     "reference tracking: tp->snd_cwnd after bpf_sk_fullsock(sk) and bpf_tcp_sock(sk)",
0804     .insns = {
0805     BPF_SK_LOOKUP(sk_lookup_tcp),
0806     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0807     BPF_EXIT_INSN(),
0808     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0809     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0810     BPF_EMIT_CALL(BPF_FUNC_sk_fullsock),
0811     BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
0812     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0813     BPF_EMIT_CALL(BPF_FUNC_tcp_sock),
0814     BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
0815     BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 3),
0816     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0817     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0818     BPF_EXIT_INSN(),
0819     BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_8, offsetof(struct bpf_tcp_sock, snd_cwnd)),
0820     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0821     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0822     BPF_EXIT_INSN(),
0823     },
0824     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0825     .result = REJECT,
0826     .errstr = "invalid mem access",
0827 },
0828 {
0829     "reference tracking: branch tracking valid pointer null comparison",
0830     .insns = {
0831     BPF_SK_LOOKUP(sk_lookup_tcp),
0832     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0833     BPF_MOV64_IMM(BPF_REG_3, 1),
0834     BPF_JMP_IMM(BPF_JNE, BPF_REG_6, 0, 1),
0835     BPF_MOV64_IMM(BPF_REG_3, 0),
0836     BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 2),
0837     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0838     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0839     BPF_EXIT_INSN(),
0840     },
0841     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0842     .result = ACCEPT,
0843 },
0844 {
0845     "reference tracking: branch tracking valid pointer value comparison",
0846     .insns = {
0847     BPF_SK_LOOKUP(sk_lookup_tcp),
0848     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0849     BPF_MOV64_IMM(BPF_REG_3, 1),
0850     BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 4),
0851     BPF_MOV64_IMM(BPF_REG_3, 0),
0852     BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 1234, 2),
0853     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0854     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0855     BPF_EXIT_INSN(),
0856     },
0857     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0858     .errstr = "Unreleased reference",
0859     .result = REJECT,
0860 },
0861 {
0862     "reference tracking: bpf_sk_release(btf_tcp_sock)",
0863     .insns = {
0864     BPF_SK_LOOKUP(sk_lookup_tcp),
0865     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0866     BPF_EXIT_INSN(),
0867     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0868     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0869     BPF_EMIT_CALL(BPF_FUNC_skc_to_tcp_sock),
0870     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
0871     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0872     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0873     BPF_EXIT_INSN(),
0874     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0875     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0876     BPF_EXIT_INSN(),
0877     },
0878     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0879     .result = ACCEPT,
0880     .result_unpriv = REJECT,
0881     .errstr_unpriv = "unknown func",
0882 },
0883 {
0884     "reference tracking: use ptr from bpf_skc_to_tcp_sock() after release",
0885     .insns = {
0886     BPF_SK_LOOKUP(sk_lookup_tcp),
0887     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0888     BPF_EXIT_INSN(),
0889     BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
0890     BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0891     BPF_EMIT_CALL(BPF_FUNC_skc_to_tcp_sock),
0892     BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 3),
0893     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0894     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0895     BPF_EXIT_INSN(),
0896     BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
0897     BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0898     BPF_EMIT_CALL(BPF_FUNC_sk_release),
0899     BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_7, 0),
0900     BPF_EXIT_INSN(),
0901     },
0902     .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0903     .result = REJECT,
0904     .errstr = "invalid mem access",
0905     .result_unpriv = REJECT,
0906     .errstr_unpriv = "unknown func",
0907 },