0001 {
0002 "runtime/jit: tail_call within bounds, prog once",
0003 .insns = {
0004 BPF_MOV64_IMM(BPF_REG_3, 0),
0005 BPF_LD_MAP_FD(BPF_REG_2, 0),
0006 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0007 BPF_MOV64_IMM(BPF_REG_0, 1),
0008 BPF_EXIT_INSN(),
0009 },
0010 .fixup_prog1 = { 1 },
0011 .result = ACCEPT,
0012 .retval = 42,
0013 },
0014 {
0015 "runtime/jit: tail_call within bounds, prog loop",
0016 .insns = {
0017 BPF_MOV64_IMM(BPF_REG_3, 1),
0018 BPF_LD_MAP_FD(BPF_REG_2, 0),
0019 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0020 BPF_MOV64_IMM(BPF_REG_0, 1),
0021 BPF_EXIT_INSN(),
0022 },
0023 .fixup_prog1 = { 1 },
0024 .result = ACCEPT,
0025 .retval = 41,
0026 },
0027 {
0028 "runtime/jit: tail_call within bounds, no prog",
0029 .insns = {
0030 BPF_MOV64_IMM(BPF_REG_3, 3),
0031 BPF_LD_MAP_FD(BPF_REG_2, 0),
0032 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0033 BPF_MOV64_IMM(BPF_REG_0, 1),
0034 BPF_EXIT_INSN(),
0035 },
0036 .fixup_prog1 = { 1 },
0037 .result = ACCEPT,
0038 .retval = 1,
0039 },
0040 {
0041 "runtime/jit: tail_call within bounds, key 2",
0042 .insns = {
0043 BPF_MOV64_IMM(BPF_REG_3, 2),
0044 BPF_LD_MAP_FD(BPF_REG_2, 0),
0045 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0046 BPF_MOV64_IMM(BPF_REG_0, 1),
0047 BPF_EXIT_INSN(),
0048 },
0049 .fixup_prog1 = { 1 },
0050 .result = ACCEPT,
0051 .retval = 24,
0052 },
0053 {
0054 "runtime/jit: tail_call within bounds, key 2 / key 2, first branch",
0055 .insns = {
0056 BPF_MOV64_IMM(BPF_REG_0, 13),
0057 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
0058 offsetof(struct __sk_buff, cb[0])),
0059 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
0060 offsetof(struct __sk_buff, cb[0])),
0061 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4),
0062 BPF_MOV64_IMM(BPF_REG_3, 2),
0063 BPF_LD_MAP_FD(BPF_REG_2, 0),
0064 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
0065 BPF_MOV64_IMM(BPF_REG_3, 2),
0066 BPF_LD_MAP_FD(BPF_REG_2, 0),
0067 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0068 BPF_MOV64_IMM(BPF_REG_0, 1),
0069 BPF_EXIT_INSN(),
0070 },
0071 .fixup_prog1 = { 5, 9 },
0072 .result = ACCEPT,
0073 .retval = 24,
0074 },
0075 {
0076 "runtime/jit: tail_call within bounds, key 2 / key 2, second branch",
0077 .insns = {
0078 BPF_MOV64_IMM(BPF_REG_0, 14),
0079 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
0080 offsetof(struct __sk_buff, cb[0])),
0081 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
0082 offsetof(struct __sk_buff, cb[0])),
0083 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4),
0084 BPF_MOV64_IMM(BPF_REG_3, 2),
0085 BPF_LD_MAP_FD(BPF_REG_2, 0),
0086 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
0087 BPF_MOV64_IMM(BPF_REG_3, 2),
0088 BPF_LD_MAP_FD(BPF_REG_2, 0),
0089 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0090 BPF_MOV64_IMM(BPF_REG_0, 1),
0091 BPF_EXIT_INSN(),
0092 },
0093 .fixup_prog1 = { 5, 9 },
0094 .result = ACCEPT,
0095 .retval = 24,
0096 },
0097 {
0098 "runtime/jit: tail_call within bounds, key 0 / key 2, first branch",
0099 .insns = {
0100 BPF_MOV64_IMM(BPF_REG_0, 13),
0101 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
0102 offsetof(struct __sk_buff, cb[0])),
0103 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
0104 offsetof(struct __sk_buff, cb[0])),
0105 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4),
0106 BPF_MOV64_IMM(BPF_REG_3, 0),
0107 BPF_LD_MAP_FD(BPF_REG_2, 0),
0108 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
0109 BPF_MOV64_IMM(BPF_REG_3, 2),
0110 BPF_LD_MAP_FD(BPF_REG_2, 0),
0111 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0112 BPF_MOV64_IMM(BPF_REG_0, 1),
0113 BPF_EXIT_INSN(),
0114 },
0115 .fixup_prog1 = { 5, 9 },
0116 .result = ACCEPT,
0117 .retval = 24,
0118 },
0119 {
0120 "runtime/jit: tail_call within bounds, key 0 / key 2, second branch",
0121 .insns = {
0122 BPF_MOV64_IMM(BPF_REG_0, 14),
0123 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
0124 offsetof(struct __sk_buff, cb[0])),
0125 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
0126 offsetof(struct __sk_buff, cb[0])),
0127 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4),
0128 BPF_MOV64_IMM(BPF_REG_3, 0),
0129 BPF_LD_MAP_FD(BPF_REG_2, 0),
0130 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
0131 BPF_MOV64_IMM(BPF_REG_3, 2),
0132 BPF_LD_MAP_FD(BPF_REG_2, 0),
0133 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0134 BPF_MOV64_IMM(BPF_REG_0, 1),
0135 BPF_EXIT_INSN(),
0136 },
0137 .fixup_prog1 = { 5, 9 },
0138 .result = ACCEPT,
0139 .retval = 42,
0140 },
0141 {
0142 "runtime/jit: tail_call within bounds, different maps, first branch",
0143 .insns = {
0144 BPF_MOV64_IMM(BPF_REG_0, 13),
0145 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
0146 offsetof(struct __sk_buff, cb[0])),
0147 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
0148 offsetof(struct __sk_buff, cb[0])),
0149 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4),
0150 BPF_MOV64_IMM(BPF_REG_3, 0),
0151 BPF_LD_MAP_FD(BPF_REG_2, 0),
0152 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
0153 BPF_MOV64_IMM(BPF_REG_3, 0),
0154 BPF_LD_MAP_FD(BPF_REG_2, 0),
0155 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0156 BPF_MOV64_IMM(BPF_REG_0, 1),
0157 BPF_EXIT_INSN(),
0158 },
0159 .fixup_prog1 = { 5 },
0160 .fixup_prog2 = { 9 },
0161 .result_unpriv = REJECT,
0162 .errstr_unpriv = "tail_call abusing map_ptr",
0163 .result = ACCEPT,
0164 .retval = 1,
0165 },
0166 {
0167 "runtime/jit: tail_call within bounds, different maps, second branch",
0168 .insns = {
0169 BPF_MOV64_IMM(BPF_REG_0, 14),
0170 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_0,
0171 offsetof(struct __sk_buff, cb[0])),
0172 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1,
0173 offsetof(struct __sk_buff, cb[0])),
0174 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 13, 4),
0175 BPF_MOV64_IMM(BPF_REG_3, 0),
0176 BPF_LD_MAP_FD(BPF_REG_2, 0),
0177 BPF_JMP_IMM(BPF_JA, 0, 0, 3),
0178 BPF_MOV64_IMM(BPF_REG_3, 0),
0179 BPF_LD_MAP_FD(BPF_REG_2, 0),
0180 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0181 BPF_MOV64_IMM(BPF_REG_0, 1),
0182 BPF_EXIT_INSN(),
0183 },
0184 .fixup_prog1 = { 5 },
0185 .fixup_prog2 = { 9 },
0186 .result_unpriv = REJECT,
0187 .errstr_unpriv = "tail_call abusing map_ptr",
0188 .result = ACCEPT,
0189 .retval = 42,
0190 },
0191 {
0192 "runtime/jit: tail_call out of bounds",
0193 .insns = {
0194 BPF_MOV64_IMM(BPF_REG_3, 256),
0195 BPF_LD_MAP_FD(BPF_REG_2, 0),
0196 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0197 BPF_MOV64_IMM(BPF_REG_0, 2),
0198 BPF_EXIT_INSN(),
0199 },
0200 .fixup_prog1 = { 1 },
0201 .result = ACCEPT,
0202 .retval = 2,
0203 },
0204 {
0205 "runtime/jit: pass negative index to tail_call",
0206 .insns = {
0207 BPF_MOV64_IMM(BPF_REG_3, -1),
0208 BPF_LD_MAP_FD(BPF_REG_2, 0),
0209 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0210 BPF_MOV64_IMM(BPF_REG_0, 2),
0211 BPF_EXIT_INSN(),
0212 },
0213 .fixup_prog1 = { 1 },
0214 .result = ACCEPT,
0215 .retval = 2,
0216 },
0217 {
0218 "runtime/jit: pass > 32bit index to tail_call",
0219 .insns = {
0220 BPF_LD_IMM64(BPF_REG_3, 0x100000000ULL),
0221 BPF_LD_MAP_FD(BPF_REG_2, 0),
0222 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_tail_call),
0223 BPF_MOV64_IMM(BPF_REG_0, 2),
0224 BPF_EXIT_INSN(),
0225 },
0226 .fixup_prog1 = { 2 },
0227 .result = ACCEPT,
0228 .retval = 42,
0229
0230 .retval_unpriv = 2,
0231 },