0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <stdio.h>
0014 #include <stdlib.h>
0015 #include <string.h>
0016
0017 #include "bpf-helper.h"
0018
0019 int bpf_resolve_jumps(struct bpf_labels *labels,
0020 struct sock_filter *filter, size_t count)
0021 {
0022 size_t i;
0023
0024 if (count < 1 || count > BPF_MAXINSNS)
0025 return -1;
0026
0027
0028
0029
0030 for (i = 0; i < count; ++i) {
0031 size_t offset = count - i - 1;
0032 struct sock_filter *instr = &filter[offset];
0033 if (instr->code != (BPF_JMP+BPF_JA))
0034 continue;
0035 switch ((instr->jt<<8)|instr->jf) {
0036 case (JUMP_JT<<8)|JUMP_JF:
0037 if (labels->labels[instr->k].location == 0xffffffff) {
0038 fprintf(stderr, "Unresolved label: '%s'\n",
0039 labels->labels[instr->k].label);
0040 return 1;
0041 }
0042 instr->k = labels->labels[instr->k].location -
0043 (offset + 1);
0044 instr->jt = 0;
0045 instr->jf = 0;
0046 continue;
0047 case (LABEL_JT<<8)|LABEL_JF:
0048 if (labels->labels[instr->k].location != 0xffffffff) {
0049 fprintf(stderr, "Duplicate label use: '%s'\n",
0050 labels->labels[instr->k].label);
0051 return 1;
0052 }
0053 labels->labels[instr->k].location = offset;
0054 instr->k = 0;
0055 instr->jt = 0;
0056 instr->jf = 0;
0057 continue;
0058 }
0059 }
0060 return 0;
0061 }
0062
0063
0064 __u32 seccomp_bpf_label(struct bpf_labels *labels, const char *label)
0065 {
0066 struct __bpf_label *begin = labels->labels, *end;
0067 int id;
0068
0069 if (labels->count == BPF_LABELS_MAX) {
0070 fprintf(stderr, "Too many labels\n");
0071 exit(1);
0072 }
0073 if (labels->count == 0) {
0074 begin->label = label;
0075 begin->location = 0xffffffff;
0076 labels->count++;
0077 return 0;
0078 }
0079 end = begin + labels->count;
0080 for (id = 0; begin < end; ++begin, ++id) {
0081 if (!strcmp(label, begin->label))
0082 return id;
0083 }
0084 begin->label = label;
0085 begin->location = 0xffffffff;
0086 labels->count++;
0087 return id;
0088 }
0089
0090 void seccomp_bpf_print(struct sock_filter *filter, size_t count)
0091 {
0092 struct sock_filter *end = filter + count;
0093 for ( ; filter < end; ++filter)
0094 printf("{ code=%u,jt=%u,jf=%u,k=%u },\n",
0095 filter->code, filter->jt, filter->jf, filter->k);
0096 }