Skip to content

Commit 2696e11

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2020-02-07 The following pull-request contains BPF updates for your *net* tree. We've added 15 non-merge commits during the last 10 day(s) which contain a total of 12 files changed, 114 insertions(+), 31 deletions(-). The main changes are: 1) Various BPF sockmap fixes related to RCU handling in the map's tear- down code, from Jakub Sitnicki. 2) Fix macro state explosion in BPF sk_storage map when calculating its bucket_log on allocation, from Martin KaFai Lau. 3) Fix potential BPF sockmap update race by rechecking socket's established state under lock, from Lorenz Bauer. 4) Fix crash in bpftool on missing xlated instructions when kptr_restrict sysctl is set, from Toke Høiland-Jørgensen. 5) Fix i40e's XSK wakeup code to return proper error in busy state and various misc fixes in xdpsock BPF sample code, from Maciej Fijalkowski. 6) Fix the way modifiers are skipped in BTF in the verifier while walking pointers to avoid program rejection, from Alexei Starovoitov. 7) Fix Makefile for runqslower BPF tool to i) rebuild on libbpf changes and ii) to fix undefined reference linker errors for older gcc version due to order of passed gcc parameters, from Yulia Kartseva and Song Liu. 8) Fix a trampoline_count BPF kselftest warning about missing braces around initializer, from Andrii Nakryiko. 9) Fix up redundant "HAVE" prefix from large INSN limit kernel probe in bpftool, from Michal Rostecki. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents dfa7f70 + 88d6f13 commit 2696e11

File tree

12 files changed

+114
-31
lines changed

12 files changed

+114
-31
lines changed

drivers/net/ethernet/intel/i40e/i40e_xsk.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ int i40e_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
791791
struct i40e_ring *ring;
792792

793793
if (test_bit(__I40E_CONFIG_BUSY, pf->state))
794-
return -ENETDOWN;
794+
return -EAGAIN;
795795

796796
if (test_bit(__I40E_VSI_DOWN, vsi->state))
797797
return -ENETDOWN;

include/linux/bpf.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ struct bpf_struct_ops {
728728
#if defined(CONFIG_BPF_JIT) && defined(CONFIG_BPF_SYSCALL)
729729
#define BPF_MODULE_OWNER ((void *)((0xeB9FUL << 2) + POISON_POINTER_DELTA))
730730
const struct bpf_struct_ops *bpf_struct_ops_find(u32 type_id);
731-
void bpf_struct_ops_init(struct btf *btf);
731+
void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log);
732732
bool bpf_struct_ops_get(const void *kdata);
733733
void bpf_struct_ops_put(const void *kdata);
734734
int bpf_struct_ops_map_sys_lookup_elem(struct bpf_map *map, void *key,
@@ -752,7 +752,10 @@ static inline const struct bpf_struct_ops *bpf_struct_ops_find(u32 type_id)
752752
{
753753
return NULL;
754754
}
755-
static inline void bpf_struct_ops_init(struct btf *btf) { }
755+
static inline void bpf_struct_ops_init(struct btf *btf,
756+
struct bpf_verifier_log *log)
757+
{
758+
}
756759
static inline bool bpf_try_module_get(const void *data, struct module *owner)
757760
{
758761
return try_module_get(owner);

kernel/bpf/bpf_struct_ops.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,11 @@ const struct bpf_prog_ops bpf_struct_ops_prog_ops = {
9696

9797
static const struct btf_type *module_type;
9898

99-
void bpf_struct_ops_init(struct btf *btf)
99+
void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log)
100100
{
101101
s32 type_id, value_id, module_id;
102102
const struct btf_member *member;
103103
struct bpf_struct_ops *st_ops;
104-
struct bpf_verifier_log log = {};
105104
const struct btf_type *t;
106105
char value_name[128];
107106
const char *mname;
@@ -172,7 +171,7 @@ void bpf_struct_ops_init(struct btf *btf)
172171
member->type,
173172
NULL);
174173
if (func_proto &&
175-
btf_distill_func_proto(&log, btf,
174+
btf_distill_func_proto(log, btf,
176175
func_proto, mname,
177176
&st_ops->func_models[j])) {
178177
pr_warn("Error in parsing func ptr %s in struct %s\n",

kernel/bpf/btf.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3643,7 +3643,7 @@ struct btf *btf_parse_vmlinux(void)
36433643
goto errout;
36443644
}
36453645

3646-
bpf_struct_ops_init(btf);
3646+
bpf_struct_ops_init(btf, log);
36473647

36483648
btf_verifier_env_free(env);
36493649
refcount_set(&btf->refcnt, 1);
@@ -3931,6 +3931,7 @@ int btf_struct_access(struct bpf_verifier_log *log,
39313931

39323932
if (btf_type_is_ptr(mtype)) {
39333933
const struct btf_type *stype;
3934+
u32 id;
39343935

39353936
if (msize != size || off != moff) {
39363937
bpf_log(log,
@@ -3939,12 +3940,9 @@ int btf_struct_access(struct bpf_verifier_log *log,
39393940
return -EACCES;
39403941
}
39413942

3942-
stype = btf_type_by_id(btf_vmlinux, mtype->type);
3943-
/* skip modifiers */
3944-
while (btf_type_is_modifier(stype))
3945-
stype = btf_type_by_id(btf_vmlinux, stype->type);
3943+
stype = btf_type_skip_modifiers(btf_vmlinux, mtype->type, &id);
39463944
if (btf_type_is_struct(stype)) {
3947-
*next_btf_id = mtype->type;
3945+
*next_btf_id = id;
39483946
return PTR_TO_BTF_ID;
39493947
}
39503948
}

net/core/bpf_sk_storage.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -643,9 +643,10 @@ static struct bpf_map *bpf_sk_storage_map_alloc(union bpf_attr *attr)
643643
return ERR_PTR(-ENOMEM);
644644
bpf_map_init_from_attr(&smap->map, attr);
645645

646+
nbuckets = roundup_pow_of_two(num_possible_cpus());
646647
/* Use at least 2 buckets, select_bucket() is undefined behavior with 1 bucket */
647-
smap->bucket_log = max_t(u32, 1, ilog2(roundup_pow_of_two(num_possible_cpus())));
648-
nbuckets = 1U << smap->bucket_log;
648+
nbuckets = max_t(u32, 2, nbuckets);
649+
smap->bucket_log = ilog2(nbuckets);
649650
cost = sizeof(*smap->buckets) * nbuckets + sizeof(*smap);
650651

651652
ret = bpf_map_charge_init(&smap->map.memory, cost);

net/core/sock_map.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ static void sock_map_free(struct bpf_map *map)
234234
int i;
235235

236236
synchronize_rcu();
237-
rcu_read_lock();
238237
raw_spin_lock_bh(&stab->lock);
239238
for (i = 0; i < stab->map.max_entries; i++) {
240239
struct sock **psk = &stab->sks[i];
@@ -243,13 +242,15 @@ static void sock_map_free(struct bpf_map *map)
243242
sk = xchg(psk, NULL);
244243
if (sk) {
245244
lock_sock(sk);
245+
rcu_read_lock();
246246
sock_map_unref(sk, psk);
247+
rcu_read_unlock();
247248
release_sock(sk);
248249
}
249250
}
250251
raw_spin_unlock_bh(&stab->lock);
251-
rcu_read_unlock();
252252

253+
/* wait for psock readers accessing its map link */
253254
synchronize_rcu();
254255

255256
bpf_map_area_free(stab->sks);
@@ -416,14 +417,16 @@ static int sock_map_update_elem(struct bpf_map *map, void *key,
416417
ret = -EINVAL;
417418
goto out;
418419
}
419-
if (!sock_map_sk_is_suitable(sk) ||
420-
sk->sk_state != TCP_ESTABLISHED) {
420+
if (!sock_map_sk_is_suitable(sk)) {
421421
ret = -EOPNOTSUPP;
422422
goto out;
423423
}
424424

425425
sock_map_sk_acquire(sk);
426-
ret = sock_map_update_common(map, idx, sk, flags);
426+
if (sk->sk_state != TCP_ESTABLISHED)
427+
ret = -EOPNOTSUPP;
428+
else
429+
ret = sock_map_update_common(map, idx, sk, flags);
427430
sock_map_sk_release(sk);
428431
out:
429432
fput(sock->file);
@@ -739,14 +742,16 @@ static int sock_hash_update_elem(struct bpf_map *map, void *key,
739742
ret = -EINVAL;
740743
goto out;
741744
}
742-
if (!sock_map_sk_is_suitable(sk) ||
743-
sk->sk_state != TCP_ESTABLISHED) {
745+
if (!sock_map_sk_is_suitable(sk)) {
744746
ret = -EOPNOTSUPP;
745747
goto out;
746748
}
747749

748750
sock_map_sk_acquire(sk);
749-
ret = sock_hash_update_common(map, key, sk, flags);
751+
if (sk->sk_state != TCP_ESTABLISHED)
752+
ret = -EOPNOTSUPP;
753+
else
754+
ret = sock_hash_update_common(map, key, sk, flags);
750755
sock_map_sk_release(sk);
751756
out:
752757
fput(sock->file);
@@ -859,19 +864,22 @@ static void sock_hash_free(struct bpf_map *map)
859864
int i;
860865

861866
synchronize_rcu();
862-
rcu_read_lock();
863867
for (i = 0; i < htab->buckets_num; i++) {
864868
bucket = sock_hash_select_bucket(htab, i);
865869
raw_spin_lock_bh(&bucket->lock);
866870
hlist_for_each_entry_safe(elem, node, &bucket->head, node) {
867871
hlist_del_rcu(&elem->node);
868872
lock_sock(elem->sk);
873+
rcu_read_lock();
869874
sock_map_unref(elem->sk, elem);
875+
rcu_read_unlock();
870876
release_sock(elem->sk);
871877
}
872878
raw_spin_unlock_bh(&bucket->lock);
873879
}
874-
rcu_read_unlock();
880+
881+
/* wait for psock readers accessing its map link */
882+
synchronize_rcu();
875883

876884
bpf_map_area_free(htab->buckets);
877885
kfree(htab);

samples/bpf/xdpsock_user.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ static u32 opt_xdp_bind_flags = XDP_USE_NEED_WAKEUP;
8383
static u32 opt_umem_flags;
8484
static int opt_unaligned_chunks;
8585
static int opt_mmap_flags;
86-
static u32 opt_xdp_bind_flags;
8786
static int opt_xsk_frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
8887
static int opt_timeout = 1000;
8988
static bool opt_need_wakeup = true;
@@ -789,7 +788,8 @@ static void kick_tx(struct xsk_socket_info *xsk)
789788
int ret;
790789

791790
ret = sendto(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0);
792-
if (ret >= 0 || errno == ENOBUFS || errno == EAGAIN || errno == EBUSY)
791+
if (ret >= 0 || errno == ENOBUFS || errno == EAGAIN ||
792+
errno == EBUSY || errno == ENETDOWN)
793793
return;
794794
exit_with_error(errno);
795795
}

tools/bpf/bpftool/feature.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ probe_large_insn_limit(const char *define_prefix, __u32 ifindex)
580580
res = bpf_probe_large_insn_limit(ifindex);
581581
print_bool_feature("have_large_insn_limit",
582582
"Large program size limit",
583-
"HAVE_LARGE_INSN_LIMIT",
583+
"LARGE_INSN_LIMIT",
584584
res, define_prefix);
585585
}
586586

tools/bpf/bpftool/prog.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
536536
buf = (unsigned char *)(info->jited_prog_insns);
537537
member_len = info->jited_prog_len;
538538
} else { /* DUMP_XLATED */
539-
if (info->xlated_prog_len == 0) {
539+
if (info->xlated_prog_len == 0 || !info->xlated_prog_insns) {
540540
p_err("error retrieving insn dump: kernel.kptr_restrict set?");
541541
return -1;
542542
}

tools/bpf/runqslower/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ clean:
4141

4242
$(OUTPUT)/runqslower: $(OUTPUT)/runqslower.o $(BPFOBJ)
4343
$(call msg,BINARY,$@)
44-
$(Q)$(CC) $(CFLAGS) -lelf -lz $^ -o $@
44+
$(Q)$(CC) $(CFLAGS) $^ -lelf -lz -o $@
4545

4646
$(OUTPUT)/runqslower.o: runqslower.h $(OUTPUT)/runqslower.skel.h \
4747
$(OUTPUT)/runqslower.bpf.o
@@ -75,7 +75,7 @@ $(OUTPUT)/vmlinux.h: $(VMLINUX_BTF_PATH) | $(OUTPUT) $(BPFTOOL)
7575
fi
7676
$(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF_PATH) format c > $@
7777

78-
$(BPFOBJ): | $(OUTPUT)
78+
$(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT)
7979
$(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) \
8080
OUTPUT=$(abspath $(dir $@))/ $(abspath $@)
8181

0 commit comments

Comments
 (0)