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

dynptr_success.c (3165B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright (c) 2022 Facebook */
      3
      4#include <string.h>
      5#include <linux/bpf.h>
      6#include <bpf/bpf_helpers.h>
      7#include "bpf_misc.h"
      8#include "errno.h"
      9
     10char _license[] SEC("license") = "GPL";
     11
     12int pid, err, val;
     13
     14struct sample {
     15	int pid;
     16	int seq;
     17	long value;
     18	char comm[16];
     19};
     20
     21struct {
     22	__uint(type, BPF_MAP_TYPE_RINGBUF);
     23} ringbuf SEC(".maps");
     24
     25struct {
     26	__uint(type, BPF_MAP_TYPE_ARRAY);
     27	__uint(max_entries, 1);
     28	__type(key, __u32);
     29	__type(value, __u32);
     30} array_map SEC(".maps");
     31
     32SEC("tp/syscalls/sys_enter_nanosleep")
     33int test_read_write(void *ctx)
     34{
     35	char write_data[64] = "hello there, world!!";
     36	char read_data[64] = {}, buf[64] = {};
     37	struct bpf_dynptr ptr;
     38	int i;
     39
     40	if (bpf_get_current_pid_tgid() >> 32 != pid)
     41		return 0;
     42
     43	bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(write_data), 0, &ptr);
     44
     45	/* Write data into the dynptr */
     46	err = err ?: bpf_dynptr_write(&ptr, 0, write_data, sizeof(write_data));
     47
     48	/* Read the data that was written into the dynptr */
     49	err = err ?: bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0);
     50
     51	/* Ensure the data we read matches the data we wrote */
     52	for (i = 0; i < sizeof(read_data); i++) {
     53		if (read_data[i] != write_data[i]) {
     54			err = 1;
     55			break;
     56		}
     57	}
     58
     59	bpf_ringbuf_discard_dynptr(&ptr, 0);
     60	return 0;
     61}
     62
     63SEC("tp/syscalls/sys_enter_nanosleep")
     64int test_data_slice(void *ctx)
     65{
     66	__u32 key = 0, val = 235, *map_val;
     67	struct bpf_dynptr ptr;
     68	__u32 map_val_size;
     69	void *data;
     70
     71	map_val_size = sizeof(*map_val);
     72
     73	if (bpf_get_current_pid_tgid() >> 32 != pid)
     74		return 0;
     75
     76	bpf_map_update_elem(&array_map, &key, &val, 0);
     77
     78	map_val = bpf_map_lookup_elem(&array_map, &key);
     79	if (!map_val) {
     80		err = 1;
     81		return 0;
     82	}
     83
     84	bpf_dynptr_from_mem(map_val, map_val_size, 0, &ptr);
     85
     86	/* Try getting a data slice that is out of range */
     87	data = bpf_dynptr_data(&ptr, map_val_size + 1, 1);
     88	if (data) {
     89		err = 2;
     90		return 0;
     91	}
     92
     93	/* Try getting more bytes than available */
     94	data = bpf_dynptr_data(&ptr, 0, map_val_size + 1);
     95	if (data) {
     96		err = 3;
     97		return 0;
     98	}
     99
    100	data = bpf_dynptr_data(&ptr, 0, sizeof(__u32));
    101	if (!data) {
    102		err = 4;
    103		return 0;
    104	}
    105
    106	*(__u32 *)data = 999;
    107
    108	err = bpf_probe_read_kernel(&val, sizeof(val), data);
    109	if (err)
    110		return 0;
    111
    112	if (val != *(int *)data)
    113		err = 5;
    114
    115	return 0;
    116}
    117
    118static int ringbuf_callback(__u32 index, void *data)
    119{
    120	struct sample *sample;
    121
    122	struct bpf_dynptr *ptr = (struct bpf_dynptr *)data;
    123
    124	sample = bpf_dynptr_data(ptr, 0, sizeof(*sample));
    125	if (!sample)
    126		err = 2;
    127	else
    128		sample->pid += index;
    129
    130	return 0;
    131}
    132
    133SEC("tp/syscalls/sys_enter_nanosleep")
    134int test_ringbuf(void *ctx)
    135{
    136	struct bpf_dynptr ptr;
    137	struct sample *sample;
    138
    139	if (bpf_get_current_pid_tgid() >> 32 != pid)
    140		return 0;
    141
    142	val = 100;
    143
    144	/* check that you can reserve a dynamic size reservation */
    145	err = bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
    146
    147	sample = err ? NULL : bpf_dynptr_data(&ptr, 0, sizeof(*sample));
    148	if (!sample) {
    149		err = 1;
    150		goto done;
    151	}
    152
    153	sample->pid = 10;
    154
    155	/* Can pass dynptr to callback functions */
    156	bpf_loop(10, ringbuf_callback, &ptr, 0);
    157
    158	if (sample->pid != 55)
    159		err = 2;
    160
    161done:
    162	bpf_ringbuf_discard_dynptr(&ptr, 0);
    163	return 0;
    164}