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
Loading
Loading
Loading
Loading
+19 −19
Original line number Diff line number Diff line
@@ -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;
		}
	}