Root/samples/seccomp/bpf-helper.c

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

Archive Download this file



interactive