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

test_subprogs.c (2636B)


      1#include "vmlinux.h"
      2#include <bpf/bpf_helpers.h>
      3#include <bpf/bpf_core_read.h>
      4
      5const char LICENSE[] SEC("license") = "GPL";
      6
      7struct {
      8	__uint(type, BPF_MAP_TYPE_ARRAY);
      9	__uint(max_entries, 1);
     10	__type(key, __u32);
     11	__type(value, __u64);
     12} array SEC(".maps");
     13
     14__noinline int sub1(int x)
     15{
     16	int key = 0;
     17
     18	bpf_map_lookup_elem(&array, &key);
     19	return x + 1;
     20}
     21
     22static __noinline int sub5(int v);
     23
     24__noinline int sub2(int y)
     25{
     26	return sub5(y + 2);
     27}
     28
     29static __noinline int sub3(int z)
     30{
     31	return z + 3 + sub1(4);
     32}
     33
     34static __noinline int sub4(int w)
     35{
     36	int key = 0;
     37
     38	bpf_map_lookup_elem(&array, &key);
     39	return w + sub3(5) + sub1(6);
     40}
     41
     42/* sub5() is an identitify function, just to test weirder functions layout and
     43 * call patterns
     44 */
     45static __noinline int sub5(int v)
     46{
     47	return sub1(v) - 1; /* compensates sub1()'s + 1 */
     48}
     49
     50/* unfortunately verifier rejects `struct task_struct *t` as an unkown pointer
     51 * type, so we need to accept pointer as integer and then cast it inside the
     52 * function
     53 */
     54__noinline int get_task_tgid(uintptr_t t)
     55{
     56	/* this ensures that CO-RE relocs work in multi-subprogs .text */
     57	return BPF_CORE_READ((struct task_struct *)(void *)t, tgid);
     58}
     59
     60int res1 = 0;
     61int res2 = 0;
     62int res3 = 0;
     63int res4 = 0;
     64
     65SEC("raw_tp/sys_enter")
     66int prog1(void *ctx)
     67{
     68	/* perform some CO-RE relocations to ensure they work with multi-prog
     69	 * sections correctly
     70	 */
     71	struct task_struct *t = (void *)bpf_get_current_task();
     72
     73	if (!BPF_CORE_READ(t, pid) || !get_task_tgid((uintptr_t)t))
     74		return 1;
     75
     76	res1 = sub1(1) + sub3(2); /* (1 + 1) + (2 + 3 + (4 + 1)) = 12 */
     77	return 0;
     78}
     79
     80SEC("raw_tp/sys_exit")
     81int prog2(void *ctx)
     82{
     83	struct task_struct *t = (void *)bpf_get_current_task();
     84
     85	if (!BPF_CORE_READ(t, pid) || !get_task_tgid((uintptr_t)t))
     86		return 1;
     87
     88	res2 = sub2(3) + sub3(4); /* (3 + 2) + (4 + 3 + (4 + 1)) = 17 */
     89	return 0;
     90}
     91
     92static int empty_callback(__u32 index, void *data)
     93{
     94	return 0;
     95}
     96
     97/* prog3 has the same section name as prog1 */
     98SEC("raw_tp/sys_enter")
     99int prog3(void *ctx)
    100{
    101	struct task_struct *t = (void *)bpf_get_current_task();
    102
    103	if (!BPF_CORE_READ(t, pid) || !get_task_tgid((uintptr_t)t))
    104		return 1;
    105
    106	/* test that ld_imm64 with BPF_PSEUDO_FUNC doesn't get blinded */
    107	bpf_loop(1, empty_callback, NULL, 0);
    108
    109	res3 = sub3(5) + 6; /* (5 + 3 + (4 + 1)) + 6 = 19 */
    110	return 0;
    111}
    112
    113/* prog4 has the same section name as prog2 */
    114SEC("raw_tp/sys_exit")
    115int prog4(void *ctx)
    116{
    117	struct task_struct *t = (void *)bpf_get_current_task();
    118
    119	if (!BPF_CORE_READ(t, pid) || !get_task_tgid((uintptr_t)t))
    120		return 1;
    121
    122	res4 = sub4(7) + sub1(8); /* (7 + (5 + 3 + (4 + 1)) + (6 + 1)) + (8 + 1) = 36 */
    123	return 0;
    124}