cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

search_pruning.c (7566B)


      1{
      2	"pointer/scalar confusion in state equality check (way 1)",
      3	.insns = {
      4	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
      5	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
      6	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
      7	BPF_LD_MAP_FD(BPF_REG_1, 0),
      8	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
      9	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
     10	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
     11	BPF_JMP_A(1),
     12	BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
     13	BPF_JMP_A(0),
     14	BPF_EXIT_INSN(),
     15	},
     16	.fixup_map_hash_8b = { 3 },
     17	.result = ACCEPT,
     18	.retval = POINTER_VALUE,
     19	.result_unpriv = REJECT,
     20	.errstr_unpriv = "R0 leaks addr as return value"
     21},
     22{
     23	"pointer/scalar confusion in state equality check (way 2)",
     24	.insns = {
     25	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
     26	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
     27	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
     28	BPF_LD_MAP_FD(BPF_REG_1, 0),
     29	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
     30	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
     31	BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
     32	BPF_JMP_A(1),
     33	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
     34	BPF_EXIT_INSN(),
     35	},
     36	.fixup_map_hash_8b = { 3 },
     37	.result = ACCEPT,
     38	.retval = POINTER_VALUE,
     39	.result_unpriv = REJECT,
     40	.errstr_unpriv = "R0 leaks addr as return value"
     41},
     42{
     43	"liveness pruning and write screening",
     44	.insns = {
     45	/* Get an unknown value */
     46	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
     47	/* branch conditions teach us nothing about R2 */
     48	BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
     49	BPF_MOV64_IMM(BPF_REG_0, 0),
     50	BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
     51	BPF_MOV64_IMM(BPF_REG_0, 0),
     52	BPF_EXIT_INSN(),
     53	},
     54	.errstr = "R0 !read_ok",
     55	.result = REJECT,
     56	.prog_type = BPF_PROG_TYPE_LWT_IN,
     57},
     58{
     59	"varlen_map_value_access pruning",
     60	.insns = {
     61	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
     62	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
     63	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
     64	BPF_LD_MAP_FD(BPF_REG_1, 0),
     65	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
     66	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
     67	BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
     68	BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
     69	BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
     70	BPF_MOV32_IMM(BPF_REG_1, 0),
     71	BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
     72	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
     73	BPF_JMP_IMM(BPF_JA, 0, 0, 0),
     74	BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
     75	BPF_EXIT_INSN(),
     76	},
     77	.fixup_map_hash_48b = { 3 },
     78	.errstr_unpriv = "R0 leaks addr",
     79	.errstr = "R0 unbounded memory access",
     80	.result_unpriv = REJECT,
     81	.result = REJECT,
     82	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
     83},
     84{
     85	"search pruning: all branches should be verified (nop operation)",
     86	.insns = {
     87		BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
     88		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
     89		BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
     90		BPF_LD_MAP_FD(BPF_REG_1, 0),
     91		BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
     92		BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
     93		BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
     94		BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
     95		BPF_MOV64_IMM(BPF_REG_4, 0),
     96		BPF_JMP_A(1),
     97		BPF_MOV64_IMM(BPF_REG_4, 1),
     98		BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
     99		BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
    100		BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
    101		BPF_JMP_IMM(BPF_JEQ, BPF_REG_5, 0, 2),
    102		BPF_MOV64_IMM(BPF_REG_6, 0),
    103		BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xdead),
    104		BPF_EXIT_INSN(),
    105	},
    106	.fixup_map_hash_8b = { 3 },
    107	.errstr = "R6 invalid mem access 'scalar'",
    108	.result = REJECT,
    109	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
    110},
    111{
    112	"search pruning: all branches should be verified (invalid stack access)",
    113	.insns = {
    114		BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
    115		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
    116		BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
    117		BPF_LD_MAP_FD(BPF_REG_1, 0),
    118		BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
    119		BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
    120		BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
    121		BPF_MOV64_IMM(BPF_REG_4, 0),
    122		BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
    123		BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
    124		BPF_JMP_A(1),
    125		BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -24),
    126		BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
    127		BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
    128		BPF_EXIT_INSN(),
    129	},
    130	.fixup_map_hash_8b = { 3 },
    131	.errstr = "invalid read from stack off -16+0 size 8",
    132	.result = REJECT,
    133	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
    134},
    135{
    136	"precision tracking for u32 spill/fill",
    137	.insns = {
    138		BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
    139		BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
    140		BPF_MOV32_IMM(BPF_REG_6, 32),
    141		BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
    142		BPF_MOV32_IMM(BPF_REG_6, 4),
    143		/* Additional insns to introduce a pruning point. */
    144		BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
    145		BPF_MOV64_IMM(BPF_REG_3, 0),
    146		BPF_MOV64_IMM(BPF_REG_3, 0),
    147		BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
    148		BPF_MOV64_IMM(BPF_REG_3, 0),
    149		/* u32 spill/fill */
    150		BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -8),
    151		BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_10, -8),
    152		/* out-of-bound map value access for r6=32 */
    153		BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
    154		BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
    155		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
    156		BPF_LD_MAP_FD(BPF_REG_1, 0),
    157		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
    158		BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
    159		BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
    160		BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
    161		BPF_MOV64_IMM(BPF_REG_0, 0),
    162		BPF_EXIT_INSN(),
    163	},
    164	.fixup_map_hash_8b = { 15 },
    165	.result = REJECT,
    166	.errstr = "R0 min value is outside of the allowed memory range",
    167	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
    168},
    169{
    170	"precision tracking for u32 spills, u64 fill",
    171	.insns = {
    172		BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
    173		BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
    174		BPF_MOV32_IMM(BPF_REG_7, 0xffffffff),
    175		/* Additional insns to introduce a pruning point. */
    176		BPF_MOV64_IMM(BPF_REG_3, 1),
    177		BPF_MOV64_IMM(BPF_REG_3, 1),
    178		BPF_MOV64_IMM(BPF_REG_3, 1),
    179		BPF_MOV64_IMM(BPF_REG_3, 1),
    180		BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
    181		BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
    182		BPF_MOV64_IMM(BPF_REG_3, 1),
    183		BPF_ALU32_IMM(BPF_DIV, BPF_REG_3, 0),
    184		/* u32 spills, u64 fill */
    185		BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -4),
    186		BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7, -8),
    187		BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_10, -8),
    188		/* if r8 != X goto pc+1  r8 known in fallthrough branch */
    189		BPF_JMP_IMM(BPF_JNE, BPF_REG_8, 0xffffffff, 1),
    190		BPF_MOV64_IMM(BPF_REG_3, 1),
    191		/* if r8 == X goto pc+1  condition always true on first
    192		 * traversal, so starts backtracking to mark r8 as requiring
    193		 * precision. r7 marked as needing precision. r6 not marked
    194		 * since it's not tracked.
    195		 */
    196		BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 0xffffffff, 1),
    197		/* fails if r8 correctly marked unknown after fill. */
    198		BPF_ALU32_IMM(BPF_DIV, BPF_REG_3, 0),
    199		BPF_MOV64_IMM(BPF_REG_0, 0),
    200		BPF_EXIT_INSN(),
    201	},
    202	.result = REJECT,
    203	.errstr = "div by zero",
    204	.prog_type = BPF_PROG_TYPE_TRACEPOINT,
    205},
    206{
    207	"allocated_stack",
    208	.insns = {
    209		BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
    210		BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
    211		BPF_ALU64_REG(BPF_MOV, BPF_REG_7, BPF_REG_0),
    212		BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
    213		BPF_MOV64_IMM(BPF_REG_0, 0),
    214		BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
    215		BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, -8),
    216		BPF_STX_MEM(BPF_B, BPF_REG_10, BPF_REG_7, -9),
    217		BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_10, -9),
    218		BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
    219		BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
    220		BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
    221		BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
    222		BPF_EXIT_INSN(),
    223	},
    224	.result = ACCEPT,
    225	.result_unpriv = ACCEPT,
    226	.insn_processed = 15,
    227},