diff options
| author | Ricky Zhou <rickyz@chromium.org> | 2016-10-13 13:37:28 -0400 |
|---|---|---|
| committer | Kees Cook <keescook@chromium.org> | 2016-11-01 11:58:17 -0400 |
| commit | d881d25cf5bc2fafbbfb383a475278977e1bd55a (patch) | |
| tree | 59831f33afc57b1979b4869f93944abb6febc446 /samples | |
| parent | 1ff120504f8c322a03fbce035d99e29e741da725 (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')
| -rw-r--r-- | samples/seccomp/bpf-helper.c | 38 |
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 @@ | |||
| 18 | int bpf_resolve_jumps(struct bpf_labels *labels, | 18 | int 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 | } |
