mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
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:
parent
1ff120504f
commit
d881d25cf5
1 changed files with 19 additions and 19 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue