0001 {
0002 "context stores via ST",
0003 .insns = {
0004 BPF_MOV64_IMM(BPF_REG_0, 0),
0005 BPF_ST_MEM(BPF_DW, BPF_REG_1, offsetof(struct __sk_buff, mark), 0),
0006 BPF_EXIT_INSN(),
0007 },
0008 .errstr = "BPF_ST stores into R1 ctx is not allowed",
0009 .result = REJECT,
0010 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0011 },
0012 {
0013 "context stores via BPF_ATOMIC",
0014 .insns = {
0015 BPF_MOV64_IMM(BPF_REG_0, 0),
0016 BPF_ATOMIC_OP(BPF_W, BPF_ADD, BPF_REG_1, BPF_REG_0, offsetof(struct __sk_buff, mark)),
0017 BPF_EXIT_INSN(),
0018 },
0019 .errstr = "BPF_ATOMIC stores into R1 ctx is not allowed",
0020 .result = REJECT,
0021 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0022 },
0023 {
0024 "arithmetic ops make PTR_TO_CTX unusable",
0025 .insns = {
0026 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1,
0027 offsetof(struct __sk_buff, data) -
0028 offsetof(struct __sk_buff, mark)),
0029 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
0030 offsetof(struct __sk_buff, mark)),
0031 BPF_EXIT_INSN(),
0032 },
0033 .errstr = "dereference of modified ctx ptr",
0034 .result = REJECT,
0035 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0036 },
0037 {
0038 "pass unmodified ctx pointer to helper",
0039 .insns = {
0040 BPF_MOV64_IMM(BPF_REG_2, 0),
0041 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0042 BPF_FUNC_csum_update),
0043 BPF_MOV64_IMM(BPF_REG_0, 0),
0044 BPF_EXIT_INSN(),
0045 },
0046 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0047 .result = ACCEPT,
0048 },
0049 {
0050 "pass modified ctx pointer to helper, 1",
0051 .insns = {
0052 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -612),
0053 BPF_MOV64_IMM(BPF_REG_2, 0),
0054 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0055 BPF_FUNC_csum_update),
0056 BPF_MOV64_IMM(BPF_REG_0, 0),
0057 BPF_EXIT_INSN(),
0058 },
0059 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0060 .result = REJECT,
0061 .errstr = "negative offset ctx ptr R1 off=-612 disallowed",
0062 },
0063 {
0064 "pass modified ctx pointer to helper, 2",
0065 .insns = {
0066 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -612),
0067 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0068 BPF_FUNC_get_socket_cookie),
0069 BPF_MOV64_IMM(BPF_REG_0, 0),
0070 BPF_EXIT_INSN(),
0071 },
0072 .result_unpriv = REJECT,
0073 .result = REJECT,
0074 .errstr_unpriv = "negative offset ctx ptr R1 off=-612 disallowed",
0075 .errstr = "negative offset ctx ptr R1 off=-612 disallowed",
0076 },
0077 {
0078 "pass modified ctx pointer to helper, 3",
0079 .insns = {
0080 BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 0),
0081 BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 4),
0082 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_3),
0083 BPF_MOV64_IMM(BPF_REG_2, 0),
0084 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0085 BPF_FUNC_csum_update),
0086 BPF_MOV64_IMM(BPF_REG_0, 0),
0087 BPF_EXIT_INSN(),
0088 },
0089 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0090 .result = REJECT,
0091 .errstr = "variable ctx access var_off=(0x0; 0x4)",
0092 },
0093 {
0094 "pass ctx or null check, 1: ctx",
0095 .insns = {
0096 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0097 BPF_FUNC_get_netns_cookie),
0098 BPF_MOV64_IMM(BPF_REG_0, 0),
0099 BPF_EXIT_INSN(),
0100 },
0101 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
0102 .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG,
0103 .result = ACCEPT,
0104 },
0105 {
0106 "pass ctx or null check, 2: null",
0107 .insns = {
0108 BPF_MOV64_IMM(BPF_REG_1, 0),
0109 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0110 BPF_FUNC_get_netns_cookie),
0111 BPF_MOV64_IMM(BPF_REG_0, 0),
0112 BPF_EXIT_INSN(),
0113 },
0114 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
0115 .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG,
0116 .result = ACCEPT,
0117 },
0118 {
0119 "pass ctx or null check, 3: 1",
0120 .insns = {
0121 BPF_MOV64_IMM(BPF_REG_1, 1),
0122 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0123 BPF_FUNC_get_netns_cookie),
0124 BPF_MOV64_IMM(BPF_REG_0, 0),
0125 BPF_EXIT_INSN(),
0126 },
0127 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
0128 .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG,
0129 .result = REJECT,
0130 .errstr = "R1 type=scalar expected=ctx",
0131 },
0132 {
0133 "pass ctx or null check, 4: ctx - const",
0134 .insns = {
0135 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -612),
0136 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0137 BPF_FUNC_get_netns_cookie),
0138 BPF_MOV64_IMM(BPF_REG_0, 0),
0139 BPF_EXIT_INSN(),
0140 },
0141 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
0142 .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG,
0143 .result = REJECT,
0144 .errstr = "negative offset ctx ptr R1 off=-612 disallowed",
0145 },
0146 {
0147 "pass ctx or null check, 5: null (connect)",
0148 .insns = {
0149 BPF_MOV64_IMM(BPF_REG_1, 0),
0150 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0151 BPF_FUNC_get_netns_cookie),
0152 BPF_MOV64_IMM(BPF_REG_0, 0),
0153 BPF_EXIT_INSN(),
0154 },
0155 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
0156 .expected_attach_type = BPF_CGROUP_INET4_CONNECT,
0157 .result = ACCEPT,
0158 },
0159 {
0160 "pass ctx or null check, 6: null (bind)",
0161 .insns = {
0162 BPF_MOV64_IMM(BPF_REG_1, 0),
0163 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0164 BPF_FUNC_get_netns_cookie),
0165 BPF_MOV64_IMM(BPF_REG_0, 0),
0166 BPF_EXIT_INSN(),
0167 },
0168 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
0169 .expected_attach_type = BPF_CGROUP_INET4_POST_BIND,
0170 .result = ACCEPT,
0171 },
0172 {
0173 "pass ctx or null check, 7: ctx (bind)",
0174 .insns = {
0175 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0176 BPF_FUNC_get_socket_cookie),
0177 BPF_MOV64_IMM(BPF_REG_0, 0),
0178 BPF_EXIT_INSN(),
0179 },
0180 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
0181 .expected_attach_type = BPF_CGROUP_INET4_POST_BIND,
0182 .result = ACCEPT,
0183 },
0184 {
0185 "pass ctx or null check, 8: null (bind)",
0186 .insns = {
0187 BPF_MOV64_IMM(BPF_REG_1, 0),
0188 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0189 BPF_FUNC_get_socket_cookie),
0190 BPF_MOV64_IMM(BPF_REG_0, 0),
0191 BPF_EXIT_INSN(),
0192 },
0193 .prog_type = BPF_PROG_TYPE_CGROUP_SOCK,
0194 .expected_attach_type = BPF_CGROUP_INET4_POST_BIND,
0195 .result = REJECT,
0196 .errstr = "R1 type=scalar expected=ctx",
0197 },