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

find_vma.c (3164B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright (c) 2021 Facebook */
      3#include <test_progs.h>
      4#include <sys/types.h>
      5#include <unistd.h>
      6#include "find_vma.skel.h"
      7#include "find_vma_fail1.skel.h"
      8#include "find_vma_fail2.skel.h"
      9
     10static void test_and_reset_skel(struct find_vma *skel, int expected_find_zero_ret, bool need_test)
     11{
     12	if (need_test) {
     13		ASSERT_EQ(skel->bss->found_vm_exec, 1, "found_vm_exec");
     14		ASSERT_EQ(skel->data->find_addr_ret, 0, "find_addr_ret");
     15		ASSERT_EQ(skel->data->find_zero_ret, expected_find_zero_ret, "find_zero_ret");
     16		ASSERT_OK_PTR(strstr(skel->bss->d_iname, "test_progs"), "find_test_progs");
     17	}
     18
     19	skel->bss->found_vm_exec = 0;
     20	skel->data->find_addr_ret = -1;
     21	skel->data->find_zero_ret = -1;
     22	skel->bss->d_iname[0] = 0;
     23}
     24
     25static int open_pe(void)
     26{
     27	struct perf_event_attr attr = {0};
     28	int pfd;
     29
     30	/* create perf event */
     31	attr.size = sizeof(attr);
     32	attr.type = PERF_TYPE_HARDWARE;
     33	attr.config = PERF_COUNT_HW_CPU_CYCLES;
     34	attr.freq = 1;
     35	attr.sample_freq = 1000;
     36	pfd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, PERF_FLAG_FD_CLOEXEC);
     37
     38	return pfd >= 0 ? pfd : -errno;
     39}
     40
     41static bool find_vma_pe_condition(struct find_vma *skel)
     42{
     43	return skel->bss->found_vm_exec == 0 ||
     44		skel->data->find_addr_ret != 0 ||
     45		skel->data->find_zero_ret == -1 ||
     46		strcmp(skel->bss->d_iname, "test_progs") != 0;
     47}
     48
     49static void test_find_vma_pe(struct find_vma *skel)
     50{
     51	struct bpf_link *link = NULL;
     52	volatile int j = 0;
     53	int pfd, i;
     54	const int one_bn = 1000000000;
     55
     56	pfd = open_pe();
     57	if (pfd < 0) {
     58		if (pfd == -ENOENT || pfd == -EOPNOTSUPP) {
     59			printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n", __func__);
     60			test__skip();
     61			goto cleanup;
     62		}
     63		if (!ASSERT_GE(pfd, 0, "perf_event_open"))
     64			goto cleanup;
     65	}
     66
     67	link = bpf_program__attach_perf_event(skel->progs.handle_pe, pfd);
     68	if (!ASSERT_OK_PTR(link, "attach_perf_event"))
     69		goto cleanup;
     70
     71	for (i = 0; i < one_bn && find_vma_pe_condition(skel); ++i)
     72		++j;
     73
     74	test_and_reset_skel(skel, -EBUSY /* in nmi, irq_work is busy */, i == one_bn);
     75cleanup:
     76	bpf_link__destroy(link);
     77	close(pfd);
     78}
     79
     80static void test_find_vma_kprobe(struct find_vma *skel)
     81{
     82	int err;
     83
     84	err = find_vma__attach(skel);
     85	if (!ASSERT_OK(err, "get_branch_snapshot__attach"))
     86		return;
     87
     88	getpgid(skel->bss->target_pid);
     89	test_and_reset_skel(skel, -ENOENT /* could not find vma for ptr 0 */, true);
     90}
     91
     92static void test_illegal_write_vma(void)
     93{
     94	struct find_vma_fail1 *skel;
     95
     96	skel = find_vma_fail1__open_and_load();
     97	if (!ASSERT_ERR_PTR(skel, "find_vma_fail1__open_and_load"))
     98		find_vma_fail1__destroy(skel);
     99}
    100
    101static void test_illegal_write_task(void)
    102{
    103	struct find_vma_fail2 *skel;
    104
    105	skel = find_vma_fail2__open_and_load();
    106	if (!ASSERT_ERR_PTR(skel, "find_vma_fail2__open_and_load"))
    107		find_vma_fail2__destroy(skel);
    108}
    109
    110void serial_test_find_vma(void)
    111{
    112	struct find_vma *skel;
    113
    114	skel = find_vma__open_and_load();
    115	if (!ASSERT_OK_PTR(skel, "find_vma__open_and_load"))
    116		return;
    117
    118	skel->bss->target_pid = getpid();
    119	skel->bss->addr = (__u64)(uintptr_t)test_find_vma_pe;
    120
    121	test_find_vma_pe(skel);
    122	test_find_vma_kprobe(skel);
    123
    124	find_vma__destroy(skel);
    125	test_illegal_write_vma();
    126	test_illegal_write_task();
    127}