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>
This commit is contained in:
Ricky Zhou 2016-10-13 10:37:28 -07:00 committed by Kees Cook
parent 1ff120504f
commit d881d25cf5

View File

@ -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;
}
}