Commit 3c2f450e authored by David S. Miller's avatar David S. Miller
Browse files


Daniel Borkmann says:

====================
pull-request: bpf 2019-12-23

The following pull-request contains BPF updates for your *net* tree.

We've added 2 non-merge commits during the last 1 day(s) which contain
a total of 4 files changed, 34 insertions(+), 31 deletions(-).

The main changes are:

1) Fix libbpf build when building on a read-only filesystem with O=dir
   option, from Namhyung Kim.

2) Fix a precision tracking bug for unknown scalars, from Daniel Borkmann.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7df2281a fa633a0f
Loading
Loading
Loading
Loading
+22 −21
Original line number Diff line number Diff line
@@ -907,7 +907,8 @@ static const int caller_saved[CALLER_SAVED_REGS] = {
	BPF_REG_0, BPF_REG_1, BPF_REG_2, BPF_REG_3, BPF_REG_4, BPF_REG_5
};

static void __mark_reg_not_init(struct bpf_reg_state *reg);
static void __mark_reg_not_init(const struct bpf_verifier_env *env,
				struct bpf_reg_state *reg);

/* Mark the unknown part of a register (variable offset or scalar value) as
 * known to have the value @imm.
@@ -945,7 +946,7 @@ static void mark_reg_known_zero(struct bpf_verifier_env *env,
		verbose(env, "mark_reg_known_zero(regs, %u)\n", regno);
		/* Something bad happened, let's kill all regs */
		for (regno = 0; regno < MAX_BPF_REG; regno++)
			__mark_reg_not_init(regs + regno);
			__mark_reg_not_init(env, regs + regno);
		return;
	}
	__mark_reg_known_zero(regs + regno);
@@ -1054,7 +1055,8 @@ static void __mark_reg_unbounded(struct bpf_reg_state *reg)
}

/* Mark a register as having a completely unknown (scalar) value. */
static void __mark_reg_unknown(struct bpf_reg_state *reg)
static void __mark_reg_unknown(const struct bpf_verifier_env *env,
			       struct bpf_reg_state *reg)
{
	/*
	 * Clear type, id, off, and union(map_ptr, range) and
@@ -1064,6 +1066,8 @@ static void __mark_reg_unknown(struct bpf_reg_state *reg)
	reg->type = SCALAR_VALUE;
	reg->var_off = tnum_unknown;
	reg->frameno = 0;
	reg->precise = env->subprog_cnt > 1 || !env->allow_ptr_leaks ?
		       true : false;
	__mark_reg_unbounded(reg);
}

@@ -1074,19 +1078,16 @@ static void mark_reg_unknown(struct bpf_verifier_env *env,
		verbose(env, "mark_reg_unknown(regs, %u)\n", regno);
		/* Something bad happened, let's kill all regs except FP */
		for (regno = 0; regno < BPF_REG_FP; regno++)
			__mark_reg_not_init(regs + regno);
			__mark_reg_not_init(env, regs + regno);
		return;
	}
	regs += regno;
	__mark_reg_unknown(regs);
	/* constant backtracking is enabled for root without bpf2bpf calls */
	regs->precise = env->subprog_cnt > 1 || !env->allow_ptr_leaks ?
			true : false;
	__mark_reg_unknown(env, regs + regno);
}

static void __mark_reg_not_init(struct bpf_reg_state *reg)
static void __mark_reg_not_init(const struct bpf_verifier_env *env,
				struct bpf_reg_state *reg)
{
	__mark_reg_unknown(reg);
	__mark_reg_unknown(env, reg);
	reg->type = NOT_INIT;
}

@@ -1097,10 +1098,10 @@ static void mark_reg_not_init(struct bpf_verifier_env *env,
		verbose(env, "mark_reg_not_init(regs, %u)\n", regno);
		/* Something bad happened, let's kill all regs except FP */
		for (regno = 0; regno < BPF_REG_FP; regno++)
			__mark_reg_not_init(regs + regno);
			__mark_reg_not_init(env, regs + regno);
		return;
	}
	__mark_reg_not_init(regs + regno);
	__mark_reg_not_init(env, regs + regno);
}

#define DEF_NOT_SUBREG	(0)
@@ -3234,7 +3235,7 @@ static int check_stack_boundary(struct bpf_verifier_env *env, int regno,
		}
		if (state->stack[spi].slot_type[0] == STACK_SPILL &&
		    state->stack[spi].spilled_ptr.type == SCALAR_VALUE) {
			__mark_reg_unknown(&state->stack[spi].spilled_ptr);
			__mark_reg_unknown(env, &state->stack[spi].spilled_ptr);
			for (j = 0; j < BPF_REG_SIZE; j++)
				state->stack[spi].slot_type[j] = STACK_MISC;
			goto mark;
@@ -3892,7 +3893,7 @@ static void __clear_all_pkt_pointers(struct bpf_verifier_env *env,
		if (!reg)
			continue;
		if (reg_is_pkt_pointer_any(reg))
			__mark_reg_unknown(reg);
			__mark_reg_unknown(env, reg);
	}
}

@@ -3920,7 +3921,7 @@ static void release_reg_references(struct bpf_verifier_env *env,
		if (!reg)
			continue;
		if (reg->ref_obj_id == ref_obj_id)
			__mark_reg_unknown(reg);
			__mark_reg_unknown(env, reg);
	}
}

@@ -4582,7 +4583,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
		/* Taint dst register if offset had invalid bounds derived from
		 * e.g. dead branches.
		 */
		__mark_reg_unknown(dst_reg);
		__mark_reg_unknown(env, dst_reg);
		return 0;
	}

@@ -4834,13 +4835,13 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
		/* Taint dst register if offset had invalid bounds derived from
		 * e.g. dead branches.
		 */
		__mark_reg_unknown(dst_reg);
		__mark_reg_unknown(env, dst_reg);
		return 0;
	}

	if (!src_known &&
	    opcode != BPF_ADD && opcode != BPF_SUB && opcode != BPF_AND) {
		__mark_reg_unknown(dst_reg);
		__mark_reg_unknown(env, dst_reg);
		return 0;
	}

@@ -6982,7 +6983,7 @@ static void clean_func_state(struct bpf_verifier_env *env,
			/* since the register is unused, clear its state
			 * to make further comparison simpler
			 */
			__mark_reg_not_init(&st->regs[i]);
			__mark_reg_not_init(env, &st->regs[i]);
	}

	for (i = 0; i < st->allocated_stack / BPF_REG_SIZE; i++) {
@@ -6990,7 +6991,7 @@ static void clean_func_state(struct bpf_verifier_env *env,
		/* liveness must not touch this stack slot anymore */
		st->stack[i].spilled_ptr.live |= REG_LIVE_DONE;
		if (!(live & REG_LIVE_READ)) {
			__mark_reg_not_init(&st->stack[i].spilled_ptr);
			__mark_reg_not_init(env, &st->stack[i].spilled_ptr);
			for (j = 0; j < BPF_REG_SIZE; j++)
				st->stack[i].slot_type[j] = STACK_INVALID;
		}
+8 −7
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ STATIC_OBJDIR := $(OUTPUT)staticobjs/
BPF_IN_SHARED	:= $(SHARED_OBJDIR)libbpf-in.o
BPF_IN_STATIC	:= $(STATIC_OBJDIR)libbpf-in.o
VERSION_SCRIPT	:= libbpf.map
BPF_HELPER_DEFS	:= $(OUTPUT)bpf_helper_defs.h

LIB_TARGET	:= $(addprefix $(OUTPUT),$(LIB_TARGET))
LIB_FILE	:= $(addprefix $(OUTPUT),$(LIB_FILE))
@@ -159,7 +160,7 @@ all: fixdep

all_cmd: $(CMD_TARGETS) check

$(BPF_IN_SHARED): force elfdep bpfdep bpf_helper_defs.h
$(BPF_IN_SHARED): force elfdep bpfdep $(BPF_HELPER_DEFS)
	@(test -f ../../include/uapi/linux/bpf.h -a -f ../../../include/uapi/linux/bpf.h && ( \
	(diff -B ../../include/uapi/linux/bpf.h ../../../include/uapi/linux/bpf.h >/dev/null) || \
	echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf.h' differs from latest version at 'include/uapi/linux/bpf.h'" >&2 )) || true
@@ -177,12 +178,12 @@ $(BPF_IN_SHARED): force elfdep bpfdep bpf_helper_defs.h
	echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_xdp.h' differs from latest version at 'include/uapi/linux/if_xdp.h'" >&2 )) || true
	$(Q)$(MAKE) $(build)=libbpf OUTPUT=$(SHARED_OBJDIR) CFLAGS="$(CFLAGS) $(SHLIB_FLAGS)"

$(BPF_IN_STATIC): force elfdep bpfdep bpf_helper_defs.h
$(BPF_IN_STATIC): force elfdep bpfdep $(BPF_HELPER_DEFS)
	$(Q)$(MAKE) $(build)=libbpf OUTPUT=$(STATIC_OBJDIR)

bpf_helper_defs.h: $(srctree)/tools/include/uapi/linux/bpf.h
$(BPF_HELPER_DEFS): $(srctree)/tools/include/uapi/linux/bpf.h
	$(Q)$(srctree)/scripts/bpf_helpers_doc.py --header 		\
		--file $(srctree)/tools/include/uapi/linux/bpf.h > bpf_helper_defs.h
		--file $(srctree)/tools/include/uapi/linux/bpf.h > $(BPF_HELPER_DEFS)

$(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION)

@@ -243,7 +244,7 @@ install_lib: all_cmd
		$(call do_install_mkdir,$(libdir_SQ)); \
		cp -fpR $(LIB_FILE) $(DESTDIR)$(libdir_SQ)

install_headers: bpf_helper_defs.h
install_headers: $(BPF_HELPER_DEFS)
	$(call QUIET_INSTALL, headers) \
		$(call do_install,bpf.h,$(prefix)/include/bpf,644); \
		$(call do_install,libbpf.h,$(prefix)/include/bpf,644); \
@@ -251,7 +252,7 @@ install_headers: bpf_helper_defs.h
		$(call do_install,libbpf_util.h,$(prefix)/include/bpf,644); \
		$(call do_install,xsk.h,$(prefix)/include/bpf,644); \
		$(call do_install,bpf_helpers.h,$(prefix)/include/bpf,644); \
		$(call do_install,bpf_helper_defs.h,$(prefix)/include/bpf,644); \
		$(call do_install,$(BPF_HELPER_DEFS),$(prefix)/include/bpf,644); \
		$(call do_install,bpf_tracing.h,$(prefix)/include/bpf,644); \
		$(call do_install,bpf_endian.h,$(prefix)/include/bpf,644); \
		$(call do_install,bpf_core_read.h,$(prefix)/include/bpf,644);
@@ -271,7 +272,7 @@ config-clean:
clean:
	$(call QUIET_CLEAN, libbpf) $(RM) -rf $(CMD_TARGETS) \
		*.o *~ *.a *.so *.so.$(LIBBPF_MAJOR_VERSION) .*.d .*.cmd \
		*.pc LIBBPF-CFLAGS bpf_helper_defs.h \
		*.pc LIBBPF-CFLAGS $(BPF_HELPER_DEFS) \
		$(SHARED_OBJDIR) $(STATIC_OBJDIR)
	$(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf

+1 −0
Original line number Diff line number Diff line
@@ -40,3 +40,4 @@ xdping
test_cpp
/no_alu32
/bpf_gcc
bpf_helper_defs.h
+3 −3
Original line number Diff line number Diff line
@@ -120,9 +120,9 @@ force:
$(BPFOBJ): force
	$(MAKE) -C $(BPFDIR) OUTPUT=$(OUTPUT)/

BPF_HELPERS := $(BPFDIR)/bpf_helper_defs.h $(wildcard $(BPFDIR)/bpf_*.h)
$(BPFDIR)/bpf_helper_defs.h:
	$(MAKE) -C $(BPFDIR) OUTPUT=$(OUTPUT)/ bpf_helper_defs.h
BPF_HELPERS := $(OUTPUT)/bpf_helper_defs.h $(wildcard $(BPFDIR)/bpf_*.h)
$(OUTPUT)/bpf_helper_defs.h:
	$(MAKE) -C $(BPFDIR) OUTPUT=$(OUTPUT)/ $(OUTPUT)/bpf_helper_defs.h

# Get Clang's default includes on this system, as opposed to those seen by
# '-target bpf'. This fixes "missing" files on some architectures/distros,