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

bpf-helper.c (2449B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Seccomp BPF helper functions
      4 *
      5 * Copyright (c) 2012 The Chromium OS Authors <chromium-os-dev@chromium.org>
      6 * Author: Will Drewry <wad@chromium.org>
      7 *
      8 * The code may be used by anyone for any purpose,
      9 * and can serve as a starting point for developing
     10 * applications using prctl(PR_ATTACH_SECCOMP_FILTER).
     11 */
     12
     13#include <stdio.h>
     14#include <stdlib.h>
     15#include <string.h>
     16
     17#include "bpf-helper.h"
     18
     19int bpf_resolve_jumps(struct bpf_labels *labels,
     20		      struct sock_filter *filter, size_t count)
     21{
     22	size_t i;
     23
     24	if (count < 1 || count > BPF_MAXINSNS)
     25		return -1;
     26	/*
     27	* Walk it once, backwards, to build the label table and do fixups.
     28	* Since backward jumps are disallowed by BPF, this is easy.
     29	*/
     30	for (i = 0; i < count; ++i) {
     31		size_t offset = count - i - 1;
     32		struct sock_filter *instr = &filter[offset];
     33		if (instr->code != (BPF_JMP+BPF_JA))
     34			continue;
     35		switch ((instr->jt<<8)|instr->jf) {
     36		case (JUMP_JT<<8)|JUMP_JF:
     37			if (labels->labels[instr->k].location == 0xffffffff) {
     38				fprintf(stderr, "Unresolved label: '%s'\n",
     39					labels->labels[instr->k].label);
     40				return 1;
     41			}
     42			instr->k = labels->labels[instr->k].location -
     43				    (offset + 1);
     44			instr->jt = 0;
     45			instr->jf = 0;
     46			continue;
     47		case (LABEL_JT<<8)|LABEL_JF:
     48			if (labels->labels[instr->k].location != 0xffffffff) {
     49				fprintf(stderr, "Duplicate label use: '%s'\n",
     50					labels->labels[instr->k].label);
     51				return 1;
     52			}
     53			labels->labels[instr->k].location = offset;
     54			instr->k = 0; /* fall through */
     55			instr->jt = 0;
     56			instr->jf = 0;
     57			continue;
     58		}
     59	}
     60	return 0;
     61}
     62
     63/* Simple lookup table for labels. */
     64__u32 seccomp_bpf_label(struct bpf_labels *labels, const char *label)
     65{
     66	struct __bpf_label *begin = labels->labels, *end;
     67	int id;
     68
     69	if (labels->count == BPF_LABELS_MAX) {
     70		fprintf(stderr, "Too many labels\n");
     71		exit(1);
     72	}
     73	if (labels->count == 0) {
     74		begin->label = label;
     75		begin->location = 0xffffffff;
     76		labels->count++;
     77		return 0;
     78	}
     79	end = begin + labels->count;
     80	for (id = 0; begin < end; ++begin, ++id) {
     81		if (!strcmp(label, begin->label))
     82			return id;
     83	}
     84	begin->label = label;
     85	begin->location = 0xffffffff;
     86	labels->count++;
     87	return id;
     88}
     89
     90void seccomp_bpf_print(struct sock_filter *filter, size_t count)
     91{
     92	struct sock_filter *end = filter + count;
     93	for ( ; filter < end; ++filter)
     94		printf("{ code=%u,jt=%u,jf=%u,k=%u },\n",
     95			filter->code, filter->jt, filter->jf, filter->k);
     96}