diff options
author | Ricky Zhou <rickyz@chromium.org> | 2016-10-13 10:37:28 -0700 |
---|---|---|
committer | Kees Cook <keescook@chromium.org> | 2016-11-01 08:58:17 -0700 |
commit | d881d25cf5bc2fafbbfb383a475278977e1bd55a (patch) | |
tree | 59831f33afc57b1979b4869f93944abb6febc446 | |
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>
-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 @@ int bpf_resolve_jumps(struct bpf_labels *labels, struct sock_filter *filter, size_t count) { - struct sock_filter *begin = filter; - __u8 insn = count - 1; + size_t i; - if (count < 1) + if (count < 1 || count > BPF_MAXINSNS) return -1; /* * Walk it once, backwards, to build the label table and do fixups. * Since backward jumps are disallowed by BPF, this is easy. */ - filter += insn; - for (; filter >= begin; --insn, --filter) { - if (filter->code != (BPF_JMP+BPF_JA)) + for (i = 0; i < count; ++i) { + size_t offset = count - i - 1; + struct sock_filter *instr = &filter[offset]; + if (instr->code != (BPF_JMP+BPF_JA)) continue; - switch ((filter->jt<<8)|filter->jf) { + switch ((instr->jt<<8)|instr->jf) { case (JUMP_JT<<8)|JUMP_JF: - if (labels->labels[filter->k].location == 0xffffffff) { + if (labels->labels[instr->k].location == 0xffffffff) { fprintf(stderr, "Unresolved label: '%s'\n", - labels->labels[filter->k].label); + labels->labels[instr->k].label); return 1; } - filter->k = labels->labels[filter->k].location - - (insn + 1); - filter->jt = 0; - filter->jf = 0; + instr->k = labels->labels[instr->k].location - + (offset + 1); + instr->jt = 0; + instr->jf = 0; continue; case (LABEL_JT<<8)|LABEL_JF: - if (labels->labels[filter->k].location != 0xffffffff) { + if (labels->labels[instr->k].location != 0xffffffff) { fprintf(stderr, "Duplicate label use: '%s'\n", - labels->labels[filter->k].label); + labels->labels[instr->k].label); return 1; } - labels->labels[filter->k].location = insn; - filter->k = 0; /* fall through */ - filter->jt = 0; - filter->jf = 0; + labels->labels[instr->k].location = offset; + instr->k = 0; /* fall through */ + instr->jt = 0; + instr->jf = 0; continue; } } |