summaryrefslogtreecommitdiffstats
path: root/samples/seccomp
diff options
context:
space:
mode:
authorRicky Zhou <rickyz@chromium.org>2016-10-13 13:37:28 -0400
committerKees Cook <keescook@chromium.org>2016-11-01 11:58:17 -0400
commitd881d25cf5bc2fafbbfb383a475278977e1bd55a (patch)
tree59831f33afc57b1979b4869f93944abb6febc446 /samples/seccomp
parent1ff120504f8c322a03fbce035d99e29e741da725 (diff)
samples/seccomp: Support programs with >256 instructions
Previously, the program size was incorrectly truncated to 8 bits, resulting in broken labels in large programs. Also changes the jump resolution loop to not rely on undefined behavior (making a pointer point before the filter array). Signed-off-by: Ricky Zhou <rickyz@chromium.org> Signed-off-by: Kees Cook <keescook@chromium.org>
Diffstat (limited to 'samples/seccomp')
-rw-r--r--samples/seccomp/bpf-helper.c38
1 files changed, 19 insertions, 19 deletions
diff --git a/samples/seccomp/bpf-helper.c b/samples/seccomp/bpf-helper.c
index 05cb4d5ff9f5..1ef0f4d72898 100644
--- a/samples/seccomp/bpf-helper.c
+++ b/samples/seccomp/bpf-helper.c
@@ -18,41 +18,41 @@
18int bpf_resolve_jumps(struct bpf_labels *labels, 18int bpf_resolve_jumps(struct bpf_labels *labels,
19 struct sock_filter *filter, size_t count) 19 struct sock_filter *filter, size_t count)
20{ 20{
21 struct sock_filter *begin = filter; 21 size_t i;
22 __u8 insn = count - 1;
23 22
24 if (count < 1) 23 if (count < 1 || count > BPF_MAXINSNS)
25 return -1; 24 return -1;
26 /* 25 /*
27 * Walk it once, backwards, to build the label table and do fixups. 26 * Walk it once, backwards, to build the label table and do fixups.
28 * Since backward jumps are disallowed by BPF, this is easy. 27 * Since backward jumps are disallowed by BPF, this is easy.
29 */ 28 */
30 filter += insn; 29 for (i = 0; i < count; ++i) {
31 for (; filter >= begin; --insn, --filter) { 30 size_t offset = count - i - 1;
32 if (filter->code != (BPF_JMP+BPF_JA)) 31 struct sock_filter *instr = &filter[offset];
32 if (instr->code != (BPF_JMP+BPF_JA))
33 continue; 33 continue;
34 switch ((filter->jt<<8)|filter->jf) { 34 switch ((instr->jt<<8)|instr->jf) {
35 case (JUMP_JT<<8)|JUMP_JF: 35 case (JUMP_JT<<8)|JUMP_JF:
36 if (labels->labels[filter->k].location == 0xffffffff) { 36 if (labels->labels[instr->k].location == 0xffffffff) {
37 fprintf(stderr, "Unresolved label: '%s'\n", 37 fprintf(stderr, "Unresolved label: '%s'\n",
38 labels->labels[filter->k].label); 38 labels->labels[instr->k].label);
39 return 1; 39 return 1;
40 } 40 }
41 filter->k = labels->labels[filter->k].location - 41 instr->k = labels->labels[instr->k].location -
42 (insn + 1); 42 (offset + 1);
43 filter->jt = 0; 43 instr->jt = 0;
44 filter->jf = 0; 44 instr->jf = 0;
45 continue; 45 continue;
46 case (LABEL_JT<<8)|LABEL_JF: 46 case (LABEL_JT<<8)|LABEL_JF:
47 if (labels->labels[filter->k].location != 0xffffffff) { 47 if (labels->labels[instr->k].location != 0xffffffff) {
48 fprintf(stderr, "Duplicate label use: '%s'\n", 48 fprintf(stderr, "Duplicate label use: '%s'\n",
49 labels->labels[filter->k].label); 49 labels->labels[instr->k].label);
50 return 1; 50 return 1;
51 } 51 }
52 labels->labels[filter->k].location = insn; 52 labels->labels[instr->k].location = offset;
53 filter->k = 0; /* fall through */ 53 instr->k = 0; /* fall through */
54 filter->jt = 0; 54 instr->jt = 0;
55 filter->jf = 0; 55 instr->jf = 0;
56 continue; 56 continue;
57 } 57 }
58 } 58 }