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

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

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
...@@ -907,7 +907,8 @@ static const int caller_saved[CALLER_SAVED_REGS] = { ...@@ -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 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 /* Mark the unknown part of a register (variable offset or scalar value) as
* known to have the value @imm. * known to have the value @imm.
...@@ -945,7 +946,7 @@ static void mark_reg_known_zero(struct bpf_verifier_env *env, ...@@ -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); verbose(env, "mark_reg_known_zero(regs, %u)\n", regno);
/* Something bad happened, let's kill all regs */ /* Something bad happened, let's kill all regs */
for (regno = 0; regno < MAX_BPF_REG; regno++) for (regno = 0; regno < MAX_BPF_REG; regno++)
__mark_reg_not_init(regs + regno); __mark_reg_not_init(env, regs + regno);
return; return;
} }
__mark_reg_known_zero(regs + regno); __mark_reg_known_zero(regs + regno);
...@@ -1054,7 +1055,8 @@ static void __mark_reg_unbounded(struct bpf_reg_state *reg) ...@@ -1054,7 +1055,8 @@ static void __mark_reg_unbounded(struct bpf_reg_state *reg)
} }
/* Mark a register as having a completely unknown (scalar) value. */ /* 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 * Clear type, id, off, and union(map_ptr, range) and
...@@ -1064,6 +1066,8 @@ static void __mark_reg_unknown(struct bpf_reg_state *reg) ...@@ -1064,6 +1066,8 @@ static void __mark_reg_unknown(struct bpf_reg_state *reg)
reg->type = SCALAR_VALUE; reg->type = SCALAR_VALUE;
reg->var_off = tnum_unknown; reg->var_off = tnum_unknown;
reg->frameno = 0; reg->frameno = 0;
reg->precise = env->subprog_cnt > 1 || !env->allow_ptr_leaks ?
true : false;
__mark_reg_unbounded(reg); __mark_reg_unbounded(reg);
} }
...@@ -1074,19 +1078,16 @@ static void mark_reg_unknown(struct bpf_verifier_env *env, ...@@ -1074,19 +1078,16 @@ static void mark_reg_unknown(struct bpf_verifier_env *env,
verbose(env, "mark_reg_unknown(regs, %u)\n", regno); verbose(env, "mark_reg_unknown(regs, %u)\n", regno);
/* Something bad happened, let's kill all regs except FP */ /* Something bad happened, let's kill all regs except FP */
for (regno = 0; regno < BPF_REG_FP; regno++) for (regno = 0; regno < BPF_REG_FP; regno++)
__mark_reg_not_init(regs + regno); __mark_reg_not_init(env, regs + regno);
return; return;
} }
regs += regno; __mark_reg_unknown(env, 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;
} }
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; reg->type = NOT_INIT;
} }
...@@ -1097,10 +1098,10 @@ static void mark_reg_not_init(struct bpf_verifier_env *env, ...@@ -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); verbose(env, "mark_reg_not_init(regs, %u)\n", regno);
/* Something bad happened, let's kill all regs except FP */ /* Something bad happened, let's kill all regs except FP */
for (regno = 0; regno < BPF_REG_FP; regno++) for (regno = 0; regno < BPF_REG_FP; regno++)
__mark_reg_not_init(regs + regno); __mark_reg_not_init(env, regs + regno);
return; return;
} }
__mark_reg_not_init(regs + regno); __mark_reg_not_init(env, regs + regno);
} }
#define DEF_NOT_SUBREG (0) #define DEF_NOT_SUBREG (0)
...@@ -3234,7 +3235,7 @@ static int check_stack_boundary(struct bpf_verifier_env *env, int regno, ...@@ -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 && if (state->stack[spi].slot_type[0] == STACK_SPILL &&
state->stack[spi].spilled_ptr.type == SCALAR_VALUE) { 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++) for (j = 0; j < BPF_REG_SIZE; j++)
state->stack[spi].slot_type[j] = STACK_MISC; state->stack[spi].slot_type[j] = STACK_MISC;
goto mark; goto mark;
...@@ -3892,7 +3893,7 @@ static void __clear_all_pkt_pointers(struct bpf_verifier_env *env, ...@@ -3892,7 +3893,7 @@ static void __clear_all_pkt_pointers(struct bpf_verifier_env *env,
if (!reg) if (!reg)
continue; continue;
if (reg_is_pkt_pointer_any(reg)) 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, ...@@ -3920,7 +3921,7 @@ static void release_reg_references(struct bpf_verifier_env *env,
if (!reg) if (!reg)
continue; continue;
if (reg->ref_obj_id == ref_obj_id) 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, ...@@ -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 /* Taint dst register if offset had invalid bounds derived from
* e.g. dead branches. * e.g. dead branches.
*/ */
__mark_reg_unknown(dst_reg); __mark_reg_unknown(env, dst_reg);
return 0; return 0;
} }
...@@ -4834,13 +4835,13 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env, ...@@ -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 /* Taint dst register if offset had invalid bounds derived from
* e.g. dead branches. * e.g. dead branches.
*/ */
__mark_reg_unknown(dst_reg); __mark_reg_unknown(env, dst_reg);
return 0; return 0;
} }
if (!src_known && if (!src_known &&
opcode != BPF_ADD && opcode != BPF_SUB && opcode != BPF_AND) { opcode != BPF_ADD && opcode != BPF_SUB && opcode != BPF_AND) {
__mark_reg_unknown(dst_reg); __mark_reg_unknown(env, dst_reg);
return 0; return 0;
} }
...@@ -6982,7 +6983,7 @@ static void clean_func_state(struct bpf_verifier_env *env, ...@@ -6982,7 +6983,7 @@ static void clean_func_state(struct bpf_verifier_env *env,
/* since the register is unused, clear its state /* since the register is unused, clear its state
* to make further comparison simpler * 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++) { 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, ...@@ -6990,7 +6991,7 @@ static void clean_func_state(struct bpf_verifier_env *env,
/* liveness must not touch this stack slot anymore */ /* liveness must not touch this stack slot anymore */
st->stack[i].spilled_ptr.live |= REG_LIVE_DONE; st->stack[i].spilled_ptr.live |= REG_LIVE_DONE;
if (!(live & REG_LIVE_READ)) { 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++) for (j = 0; j < BPF_REG_SIZE; j++)
st->stack[i].slot_type[j] = STACK_INVALID; st->stack[i].slot_type[j] = STACK_INVALID;
} }
......
...@@ -138,6 +138,7 @@ STATIC_OBJDIR := $(OUTPUT)staticobjs/ ...@@ -138,6 +138,7 @@ STATIC_OBJDIR := $(OUTPUT)staticobjs/
BPF_IN_SHARED := $(SHARED_OBJDIR)libbpf-in.o BPF_IN_SHARED := $(SHARED_OBJDIR)libbpf-in.o
BPF_IN_STATIC := $(STATIC_OBJDIR)libbpf-in.o BPF_IN_STATIC := $(STATIC_OBJDIR)libbpf-in.o
VERSION_SCRIPT := libbpf.map VERSION_SCRIPT := libbpf.map
BPF_HELPER_DEFS := $(OUTPUT)bpf_helper_defs.h
LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET)) LIB_TARGET := $(addprefix $(OUTPUT),$(LIB_TARGET))
LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE))
...@@ -159,7 +160,7 @@ all: fixdep ...@@ -159,7 +160,7 @@ all: fixdep
all_cmd: $(CMD_TARGETS) check 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 && ( \ @(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) || \ (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 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 ...@@ -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 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)" $(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) $(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 \ $(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) $(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION)
...@@ -243,7 +244,7 @@ install_lib: all_cmd ...@@ -243,7 +244,7 @@ install_lib: all_cmd
$(call do_install_mkdir,$(libdir_SQ)); \ $(call do_install_mkdir,$(libdir_SQ)); \
cp -fpR $(LIB_FILE) $(DESTDIR)$(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 QUIET_INSTALL, headers) \
$(call do_install,bpf.h,$(prefix)/include/bpf,644); \ $(call do_install,bpf.h,$(prefix)/include/bpf,644); \
$(call do_install,libbpf.h,$(prefix)/include/bpf,644); \ $(call do_install,libbpf.h,$(prefix)/include/bpf,644); \
...@@ -251,7 +252,7 @@ install_headers: bpf_helper_defs.h ...@@ -251,7 +252,7 @@ install_headers: bpf_helper_defs.h
$(call do_install,libbpf_util.h,$(prefix)/include/bpf,644); \ $(call do_install,libbpf_util.h,$(prefix)/include/bpf,644); \
$(call do_install,xsk.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_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_tracing.h,$(prefix)/include/bpf,644); \
$(call do_install,bpf_endian.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); $(call do_install,bpf_core_read.h,$(prefix)/include/bpf,644);
...@@ -271,7 +272,7 @@ config-clean: ...@@ -271,7 +272,7 @@ config-clean:
clean: clean:
$(call QUIET_CLEAN, libbpf) $(RM) -rf $(CMD_TARGETS) \ $(call QUIET_CLEAN, libbpf) $(RM) -rf $(CMD_TARGETS) \
*.o *~ *.a *.so *.so.$(LIBBPF_MAJOR_VERSION) .*.d .*.cmd \ *.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) $(SHARED_OBJDIR) $(STATIC_OBJDIR)
$(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf
......
...@@ -40,3 +40,4 @@ xdping ...@@ -40,3 +40,4 @@ xdping
test_cpp test_cpp
/no_alu32 /no_alu32
/bpf_gcc /bpf_gcc
bpf_helper_defs.h
...@@ -120,9 +120,9 @@ force: ...@@ -120,9 +120,9 @@ force:
$(BPFOBJ): force $(BPFOBJ): force
$(MAKE) -C $(BPFDIR) OUTPUT=$(OUTPUT)/ $(MAKE) -C $(BPFDIR) OUTPUT=$(OUTPUT)/
BPF_HELPERS := $(BPFDIR)/bpf_helper_defs.h $(wildcard $(BPFDIR)/bpf_*.h) BPF_HELPERS := $(OUTPUT)/bpf_helper_defs.h $(wildcard $(BPFDIR)/bpf_*.h)
$(BPFDIR)/bpf_helper_defs.h: $(OUTPUT)/bpf_helper_defs.h:
$(MAKE) -C $(BPFDIR) OUTPUT=$(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 # Get Clang's default includes on this system, as opposed to those seen by
# '-target bpf'. This fixes "missing" files on some architectures/distros, # '-target bpf'. This fixes "missing" files on some architectures/distros,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment