Skip to content
Snippets Groups Projects
Commit d881d25c authored by Ricky Zhou's avatar Ricky Zhou Committed by Kees Cook
Browse files

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: default avatarRicky Zhou <rickyz@chromium.org>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
parent 1ff12050
No related merge requests found
...@@ -18,41 +18,41 @@ ...@@ -18,41 +18,41 @@
int bpf_resolve_jumps(struct bpf_labels *labels, int bpf_resolve_jumps(struct bpf_labels *labels,
struct sock_filter *filter, size_t count) struct sock_filter *filter, size_t count)
{ {
struct sock_filter *begin = filter; size_t i;
__u8 insn = count - 1;
if (count < 1) if (count < 1 || count > BPF_MAXINSNS)
return -1; return -1;
/* /*
* Walk it once, backwards, to build the label table and do fixups. * Walk it once, backwards, to build the label table and do fixups.
* Since backward jumps are disallowed by BPF, this is easy. * Since backward jumps are disallowed by BPF, this is easy.
*/ */
filter += insn; for (i = 0; i < count; ++i) {
for (; filter >= begin; --insn, --filter) { size_t offset = count - i - 1;
if (filter->code != (BPF_JMP+BPF_JA)) struct sock_filter *instr = &filter[offset];
if (instr->code != (BPF_JMP+BPF_JA))
continue; continue;
switch ((filter->jt<<8)|filter->jf) { switch ((instr->jt<<8)|instr->jf) {
case (JUMP_JT<<8)|JUMP_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", fprintf(stderr, "Unresolved label: '%s'\n",
labels->labels[filter->k].label); labels->labels[instr->k].label);
return 1; return 1;
} }
filter->k = labels->labels[filter->k].location - instr->k = labels->labels[instr->k].location -
(insn + 1); (offset + 1);
filter->jt = 0; instr->jt = 0;
filter->jf = 0; instr->jf = 0;
continue; continue;
case (LABEL_JT<<8)|LABEL_JF: 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", fprintf(stderr, "Duplicate label use: '%s'\n",
labels->labels[filter->k].label); labels->labels[instr->k].label);
return 1; return 1;
} }
labels->labels[filter->k].location = insn; labels->labels[instr->k].location = offset;
filter->k = 0; /* fall through */ instr->k = 0; /* fall through */
filter->jt = 0; instr->jt = 0;
filter->jf = 0; instr->jf = 0;
continue; continue;
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment