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

spill_fill.c (11308B)


      1{
      2	"check valid spill/fill",
      3	.insns = {
      4	/* spill R1(ctx) into stack */
      5	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
      6	/* fill it back into R2 */
      7	BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -8),
      8	/* should be able to access R0 = *(R2 + 8) */
      9	/* BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 8), */
     10	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
     11	BPF_EXIT_INSN(),
     12	},
     13	.errstr_unpriv = "R0 leaks addr",
     14	.result = ACCEPT,
     15	.result_unpriv = REJECT,
     16	.retval = POINTER_VALUE,
     17},
     18{
     19	"check valid spill/fill, skb mark",
     20	.insns = {
     21	BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
     22	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
     23	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
     24	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
     25		    offsetof(struct __sk_buff, mark)),
     26	BPF_EXIT_INSN(),
     27	},
     28	.result = ACCEPT,
     29	.result_unpriv = ACCEPT,
     30},
     31{
     32	"check valid spill/fill, ptr to mem",
     33	.insns = {
     34	/* reserve 8 byte ringbuf memory */
     35	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
     36	BPF_LD_MAP_FD(BPF_REG_1, 0),
     37	BPF_MOV64_IMM(BPF_REG_2, 8),
     38	BPF_MOV64_IMM(BPF_REG_3, 0),
     39	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_reserve),
     40	/* store a pointer to the reserved memory in R6 */
     41	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
     42	/* check whether the reservation was successful */
     43	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
     44	/* spill R6(mem) into the stack */
     45	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
     46	/* fill it back in R7 */
     47	BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_10, -8),
     48	/* should be able to access *(R7) = 0 */
     49	BPF_ST_MEM(BPF_DW, BPF_REG_7, 0, 0),
     50	/* submit the reserved ringbuf memory */
     51	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
     52	BPF_MOV64_IMM(BPF_REG_2, 0),
     53	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_submit),
     54	BPF_MOV64_IMM(BPF_REG_0, 0),
     55	BPF_EXIT_INSN(),
     56	},
     57	.fixup_map_ringbuf = { 1 },
     58	.result = ACCEPT,
     59	.result_unpriv = ACCEPT,
     60},
     61{
     62	"check with invalid reg offset 0",
     63	.insns = {
     64	/* reserve 8 byte ringbuf memory */
     65	BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
     66	BPF_LD_MAP_FD(BPF_REG_1, 0),
     67	BPF_MOV64_IMM(BPF_REG_2, 8),
     68	BPF_MOV64_IMM(BPF_REG_3, 0),
     69	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_reserve),
     70	/* store a pointer to the reserved memory in R6 */
     71	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
     72	/* add invalid offset to memory or NULL */
     73	BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 1),
     74	/* check whether the reservation was successful */
     75	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
     76	/* should not be able to access *(R7) = 0 */
     77	BPF_ST_MEM(BPF_W, BPF_REG_6, 0, 0),
     78	/* submit the reserved ringbuf memory */
     79	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
     80	BPF_MOV64_IMM(BPF_REG_2, 0),
     81	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_submit),
     82	BPF_MOV64_IMM(BPF_REG_0, 0),
     83	BPF_EXIT_INSN(),
     84	},
     85	.fixup_map_ringbuf = { 1 },
     86	.result = REJECT,
     87	.errstr = "R0 pointer arithmetic on alloc_mem_or_null prohibited",
     88},
     89{
     90	"check corrupted spill/fill",
     91	.insns = {
     92	/* spill R1(ctx) into stack */
     93	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
     94	/* mess up with R1 pointer on stack */
     95	BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
     96	/* fill back into R0 is fine for priv.
     97	 * R0 now becomes SCALAR_VALUE.
     98	 */
     99	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
    100	/* Load from R0 should fail. */
    101	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
    102	BPF_EXIT_INSN(),
    103	},
    104	.errstr_unpriv = "attempt to corrupt spilled",
    105	.errstr = "R0 invalid mem access 'scalar'",
    106	.result = REJECT,
    107	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
    108},
    109{
    110	"check corrupted spill/fill, LSB",
    111	.insns = {
    112	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
    113	BPF_ST_MEM(BPF_H, BPF_REG_10, -8, 0xcafe),
    114	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
    115	BPF_EXIT_INSN(),
    116	},
    117	.errstr_unpriv = "attempt to corrupt spilled",
    118	.result_unpriv = REJECT,
    119	.result = ACCEPT,
    120	.retval = POINTER_VALUE,
    121},
    122{
    123	"check corrupted spill/fill, MSB",
    124	.insns = {
    125	BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
    126	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0x12345678),
    127	BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
    128	BPF_EXIT_INSN(),
    129	},
    130	.errstr_unpriv = "attempt to corrupt spilled",
    131	.result_unpriv = REJECT,
    132	.result = ACCEPT,
    133	.retval = POINTER_VALUE,
    134},
    135{
    136	"Spill and refill a u32 const scalar.  Offset to skb->data",
    137	.insns = {
    138	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
    139		    offsetof(struct __sk_buff, data)),
    140	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
    141		    offsetof(struct __sk_buff, data_end)),
    142	/* r4 = 20 */
    143	BPF_MOV32_IMM(BPF_REG_4, 20),
    144	/* *(u32 *)(r10 -8) = r4 */
    145	BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
    146	/* r4 = *(u32 *)(r10 -8) */
    147	BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_10, -8),
    148	/* r0 = r2 */
    149	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
    150	/* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=20 */
    151	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
    152	/* if (r0 > r3) R0=pkt,off=20 R2=pkt R3=pkt_end R4=20 */
    153	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
    154	/* r0 = *(u32 *)r2 R0=pkt,off=20,r=20 R2=pkt,r=20 R3=pkt_end R4=20 */
    155	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
    156	BPF_MOV64_IMM(BPF_REG_0, 0),
    157	BPF_EXIT_INSN(),
    158	},
    159	.result = ACCEPT,
    160	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
    161},
    162{
    163	"Spill a u32 const, refill from another half of the uninit u32 from the stack",
    164	.insns = {
    165	/* r4 = 20 */
    166	BPF_MOV32_IMM(BPF_REG_4, 20),
    167	/* *(u32 *)(r10 -8) = r4 */
    168	BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
    169	/* r4 = *(u32 *)(r10 -4) fp-8=????rrrr*/
    170	BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_10, -4),
    171	BPF_MOV64_IMM(BPF_REG_0, 0),
    172	BPF_EXIT_INSN(),
    173	},
    174	.result = REJECT,
    175	.errstr = "invalid read from stack off -4+0 size 4",
    176	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
    177},
    178{
    179	"Spill a u32 const scalar.  Refill as u16.  Offset to skb->data",
    180	.insns = {
    181	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
    182		    offsetof(struct __sk_buff, data)),
    183	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
    184		    offsetof(struct __sk_buff, data_end)),
    185	/* r4 = 20 */
    186	BPF_MOV32_IMM(BPF_REG_4, 20),
    187	/* *(u32 *)(r10 -8) = r4 */
    188	BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
    189	/* r4 = *(u16 *)(r10 -8) */
    190	BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_10, -8),
    191	/* r0 = r2 */
    192	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
    193	/* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=umax=65535 */
    194	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
    195	/* if (r0 > r3) R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=umax=65535 */
    196	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
    197	/* r0 = *(u32 *)r2 R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=20 */
    198	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
    199	BPF_MOV64_IMM(BPF_REG_0, 0),
    200	BPF_EXIT_INSN(),
    201	},
    202	.result = REJECT,
    203	.errstr = "invalid access to packet",
    204	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
    205},
    206{
    207	"Spill u32 const scalars.  Refill as u64.  Offset to skb->data",
    208	.insns = {
    209	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
    210		    offsetof(struct __sk_buff, data)),
    211	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
    212		    offsetof(struct __sk_buff, data_end)),
    213	/* r6 = 0 */
    214	BPF_MOV32_IMM(BPF_REG_6, 0),
    215	/* r7 = 20 */
    216	BPF_MOV32_IMM(BPF_REG_7, 20),
    217	/* *(u32 *)(r10 -4) = r6 */
    218	BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -4),
    219	/* *(u32 *)(r10 -8) = r7 */
    220	BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7, -8),
    221	/* r4 = *(u64 *)(r10 -8) */
    222	BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_10, -8),
    223	/* r0 = r2 */
    224	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
    225	/* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=umax=65535 */
    226	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
    227	/* if (r0 > r3) R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=umax=65535 */
    228	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
    229	/* r0 = *(u32 *)r2 R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=20 */
    230	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
    231	BPF_MOV64_IMM(BPF_REG_0, 0),
    232	BPF_EXIT_INSN(),
    233	},
    234	.result = REJECT,
    235	.errstr = "invalid access to packet",
    236	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
    237},
    238{
    239	"Spill a u32 const scalar.  Refill as u16 from fp-6.  Offset to skb->data",
    240	.insns = {
    241	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
    242		    offsetof(struct __sk_buff, data)),
    243	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
    244		    offsetof(struct __sk_buff, data_end)),
    245	/* r4 = 20 */
    246	BPF_MOV32_IMM(BPF_REG_4, 20),
    247	/* *(u32 *)(r10 -8) = r4 */
    248	BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
    249	/* r4 = *(u16 *)(r10 -6) */
    250	BPF_LDX_MEM(BPF_H, BPF_REG_4, BPF_REG_10, -6),
    251	/* r0 = r2 */
    252	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
    253	/* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=umax=65535 */
    254	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
    255	/* if (r0 > r3) R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=umax=65535 */
    256	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
    257	/* r0 = *(u32 *)r2 R0=pkt,umax=65535 R2=pkt R3=pkt_end R4=20 */
    258	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
    259	BPF_MOV64_IMM(BPF_REG_0, 0),
    260	BPF_EXIT_INSN(),
    261	},
    262	.result = REJECT,
    263	.errstr = "invalid access to packet",
    264	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
    265},
    266{
    267	"Spill and refill a u32 const scalar at non 8byte aligned stack addr.  Offset to skb->data",
    268	.insns = {
    269	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
    270		    offsetof(struct __sk_buff, data)),
    271	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
    272		    offsetof(struct __sk_buff, data_end)),
    273	/* r4 = 20 */
    274	BPF_MOV32_IMM(BPF_REG_4, 20),
    275	/* *(u32 *)(r10 -8) = r4 */
    276	BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
    277	/* *(u32 *)(r10 -4) = r4 */
    278	BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -4),
    279	/* r4 = *(u32 *)(r10 -4),  */
    280	BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_10, -4),
    281	/* r0 = r2 */
    282	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
    283	/* r0 += r4 R0=pkt R2=pkt R3=pkt_end R4=umax=U32_MAX */
    284	BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_4),
    285	/* if (r0 > r3) R0=pkt,umax=U32_MAX R2=pkt R3=pkt_end R4= */
    286	BPF_JMP_REG(BPF_JGT, BPF_REG_0, BPF_REG_3, 1),
    287	/* r0 = *(u32 *)r2 R0=pkt,umax=U32_MAX R2=pkt R3=pkt_end R4= */
    288	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_2, 0),
    289	BPF_MOV64_IMM(BPF_REG_0, 0),
    290	BPF_EXIT_INSN(),
    291	},
    292	.result = REJECT,
    293	.errstr = "invalid access to packet",
    294	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
    295},
    296{
    297	"Spill and refill a umax=40 bounded scalar.  Offset to skb->data",
    298	.insns = {
    299	BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
    300		    offsetof(struct __sk_buff, data)),
    301	BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
    302		    offsetof(struct __sk_buff, data_end)),
    303	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_1,
    304		    offsetof(struct __sk_buff, tstamp)),
    305	BPF_JMP_IMM(BPF_JLE, BPF_REG_4, 40, 2),
    306	BPF_MOV64_IMM(BPF_REG_0, 0),
    307	BPF_EXIT_INSN(),
    308	/* *(u32 *)(r10 -8) = r4 R4=umax=40 */
    309	BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
    310	/* r4 = (*u32 *)(r10 - 8) */
    311	BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_10, -8),
    312	/* r2 += r4 R2=pkt R4=umax=40 */
    313	BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_4),
    314	/* r0 = r2 R2=pkt,umax=40 R4=umax=40 */
    315	BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
    316	/* r2 += 20 R0=pkt,umax=40 R2=pkt,umax=40 */
    317	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 20),
    318	/* if (r2 > r3) R0=pkt,umax=40 R2=pkt,off=20,umax=40 */
    319	BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_3, 1),
    320	/* r0 = *(u32 *)r0 R0=pkt,r=20,umax=40 R2=pkt,off=20,r=20,umax=40 */
    321	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0),
    322	BPF_MOV64_IMM(BPF_REG_0, 0),
    323	BPF_EXIT_INSN(),
    324	},
    325	.result = ACCEPT,
    326	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
    327},
    328{
    329	"Spill a u32 scalar at fp-4 and then at fp-8",
    330	.insns = {
    331	/* r4 = 4321 */
    332	BPF_MOV32_IMM(BPF_REG_4, 4321),
    333	/* *(u32 *)(r10 -4) = r4 */
    334	BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -4),
    335	/* *(u32 *)(r10 -8) = r4 */
    336	BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8),
    337	/* r4 = *(u64 *)(r10 -8) */
    338	BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
    339	BPF_MOV64_IMM(BPF_REG_0, 0),
    340	BPF_EXIT_INSN(),
    341	},
    342	.result = ACCEPT,
    343	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
    344},