Skip to content

Commit fa7566a

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Alexei Starovoitov says: ==================== pull-request: bpf 2020-06-12 The following pull-request contains BPF updates for your *net* tree. We've added 26 non-merge commits during the last 10 day(s) which contain a total of 27 files changed, 348 insertions(+), 93 deletions(-). The main changes are: 1) sock_hash accounting fix, from Andrey. 2) libbpf fix and probe_mem sanitizing, from Andrii. 3) sock_hash fixes, from Jakub. 4) devmap_val fix, from Jesper. 5) load_bytes_relative fix, from YiFei. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents bf97bac + 29fcb05 commit fa7566a

File tree

27 files changed

+348
-93
lines changed

27 files changed

+348
-93
lines changed

include/uapi/linux/bpf.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3761,6 +3761,19 @@ struct xdp_md {
37613761
__u32 egress_ifindex; /* txq->dev->ifindex */
37623762
};
37633763

3764+
/* DEVMAP map-value layout
3765+
*
3766+
* The struct data-layout of map-value is a configuration interface.
3767+
* New members can only be added to the end of this structure.
3768+
*/
3769+
struct bpf_devmap_val {
3770+
__u32 ifindex; /* device index */
3771+
union {
3772+
int fd; /* prog fd on map write */
3773+
__u32 id; /* prog id on map read */
3774+
} bpf_prog;
3775+
};
3776+
37643777
enum sk_action {
37653778
SK_DROP = 0,
37663779
SK_PASS,

kernel/bpf/cgroup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ static struct bpf_prog_list *find_attach_entry(struct list_head *progs,
378378
}
379379

380380
list_for_each_entry(pl, progs, node) {
381-
if (prog && pl->prog == prog)
381+
if (prog && pl->prog == prog && prog != replace_prog)
382382
/* disallow attaching the same prog twice */
383383
return ERR_PTR(-EINVAL);
384384
if (link && pl->link == link)

kernel/bpf/devmap.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,6 @@ struct xdp_dev_bulk_queue {
6060
unsigned int count;
6161
};
6262

63-
/* DEVMAP values */
64-
struct bpf_devmap_val {
65-
u32 ifindex; /* device index */
66-
union {
67-
int fd; /* prog fd on map write */
68-
u32 id; /* prog id on map read */
69-
} bpf_prog;
70-
};
71-
7263
struct bpf_dtab_netdev {
7364
struct net_device *dev; /* must be first member, due to tracepoint */
7465
struct hlist_node index_hlist;
@@ -479,6 +470,7 @@ static struct xdp_buff *dev_map_run_prog(struct net_device *dev,
479470
struct xdp_txq_info txq = { .dev = dev };
480471
u32 act;
481472

473+
xdp_set_data_meta_invalid(xdp);
482474
xdp->txq = &txq;
483475

484476
act = bpf_prog_run_xdp(xdp_prog, xdp);
@@ -618,7 +610,7 @@ static struct bpf_dtab_netdev *__dev_map_alloc_node(struct net *net,
618610
if (!dev->dev)
619611
goto err_out;
620612

621-
if (val->bpf_prog.fd >= 0) {
613+
if (val->bpf_prog.fd > 0) {
622614
prog = bpf_prog_get_type_dev(val->bpf_prog.fd,
623615
BPF_PROG_TYPE_XDP, false);
624616
if (IS_ERR(prog))
@@ -652,8 +644,8 @@ static int __dev_map_update_elem(struct net *net, struct bpf_map *map,
652644
void *key, void *value, u64 map_flags)
653645
{
654646
struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
655-
struct bpf_devmap_val val = { .bpf_prog.fd = -1 };
656647
struct bpf_dtab_netdev *dev, *old_dev;
648+
struct bpf_devmap_val val = {};
657649
u32 i = *(u32 *)key;
658650

659651
if (unlikely(map_flags > BPF_EXIST))
@@ -669,7 +661,7 @@ static int __dev_map_update_elem(struct net *net, struct bpf_map *map,
669661
if (!val.ifindex) {
670662
dev = NULL;
671663
/* can not specify fd if ifindex is 0 */
672-
if (val.bpf_prog.fd != -1)
664+
if (val.bpf_prog.fd > 0)
673665
return -EINVAL;
674666
} else {
675667
dev = __dev_map_alloc_node(net, dtab, &val, i);
@@ -699,8 +691,8 @@ static int __dev_map_hash_update_elem(struct net *net, struct bpf_map *map,
699691
void *key, void *value, u64 map_flags)
700692
{
701693
struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
702-
struct bpf_devmap_val val = { .bpf_prog.fd = -1 };
703694
struct bpf_dtab_netdev *dev, *old_dev;
695+
struct bpf_devmap_val val = {};
704696
u32 idx = *(u32 *)key;
705697
unsigned long flags;
706698
int err = -EEXIST;

kernel/bpf/syscall.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3158,6 +3158,7 @@ static struct bpf_insn *bpf_insn_prepare_dump(const struct bpf_prog *prog)
31583158
struct bpf_insn *insns;
31593159
u32 off, type;
31603160
u64 imm;
3161+
u8 code;
31613162
int i;
31623163

31633164
insns = kmemdup(prog->insnsi, bpf_prog_insn_size(prog),
@@ -3166,21 +3167,27 @@ static struct bpf_insn *bpf_insn_prepare_dump(const struct bpf_prog *prog)
31663167
return insns;
31673168

31683169
for (i = 0; i < prog->len; i++) {
3169-
if (insns[i].code == (BPF_JMP | BPF_TAIL_CALL)) {
3170+
code = insns[i].code;
3171+
3172+
if (code == (BPF_JMP | BPF_TAIL_CALL)) {
31703173
insns[i].code = BPF_JMP | BPF_CALL;
31713174
insns[i].imm = BPF_FUNC_tail_call;
31723175
/* fall-through */
31733176
}
3174-
if (insns[i].code == (BPF_JMP | BPF_CALL) ||
3175-
insns[i].code == (BPF_JMP | BPF_CALL_ARGS)) {
3176-
if (insns[i].code == (BPF_JMP | BPF_CALL_ARGS))
3177+
if (code == (BPF_JMP | BPF_CALL) ||
3178+
code == (BPF_JMP | BPF_CALL_ARGS)) {
3179+
if (code == (BPF_JMP | BPF_CALL_ARGS))
31773180
insns[i].code = BPF_JMP | BPF_CALL;
31783181
if (!bpf_dump_raw_ok())
31793182
insns[i].imm = 0;
31803183
continue;
31813184
}
3185+
if (BPF_CLASS(code) == BPF_LDX && BPF_MODE(code) == BPF_PROBE_MEM) {
3186+
insns[i].code = BPF_LDX | BPF_SIZE(code) | BPF_MEM;
3187+
continue;
3188+
}
31823189

3183-
if (insns[i].code != (BPF_LD | BPF_IMM | BPF_DW))
3190+
if (code != (BPF_LD | BPF_IMM | BPF_DW))
31843191
continue;
31853192

31863193
imm = ((u64)insns[i + 1].imm << 32) | (u32)insns[i].imm;

kernel/bpf/verifier.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7552,7 +7552,7 @@ static int check_btf_func(struct bpf_verifier_env *env,
75527552
const struct btf *btf;
75537553
void __user *urecord;
75547554
u32 prev_offset = 0;
7555-
int ret = 0;
7555+
int ret = -ENOMEM;
75567556

75577557
nfuncs = attr->func_info_cnt;
75587558
if (!nfuncs)

kernel/trace/trace_kprobe.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1629,7 +1629,7 @@ int bpf_get_kprobe_info(const struct perf_event *event, u32 *fd_type,
16291629
if (perf_type_tracepoint)
16301630
tk = find_trace_kprobe(pevent, group);
16311631
else
1632-
tk = event->tp_event->data;
1632+
tk = trace_kprobe_primary_from_call(event->tp_event);
16331633
if (!tk)
16341634
return -EINVAL;
16351635

kernel/trace/trace_uprobe.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1412,7 +1412,7 @@ int bpf_get_uprobe_info(const struct perf_event *event, u32 *fd_type,
14121412
if (perf_type_tracepoint)
14131413
tu = find_probe_event(pevent, group);
14141414
else
1415-
tu = event->tp_event->data;
1415+
tu = trace_uprobe_primary_from_call(event->tp_event);
14161416
if (!tu)
14171417
return -EINVAL;
14181418

net/core/filter.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,25 +1755,27 @@ BPF_CALL_5(bpf_skb_load_bytes_relative, const struct sk_buff *, skb,
17551755
u32, offset, void *, to, u32, len, u32, start_header)
17561756
{
17571757
u8 *end = skb_tail_pointer(skb);
1758-
u8 *net = skb_network_header(skb);
1759-
u8 *mac = skb_mac_header(skb);
1760-
u8 *ptr;
1758+
u8 *start, *ptr;
17611759

1762-
if (unlikely(offset > 0xffff || len > (end - mac)))
1760+
if (unlikely(offset > 0xffff))
17631761
goto err_clear;
17641762

17651763
switch (start_header) {
17661764
case BPF_HDR_START_MAC:
1767-
ptr = mac + offset;
1765+
if (unlikely(!skb_mac_header_was_set(skb)))
1766+
goto err_clear;
1767+
start = skb_mac_header(skb);
17681768
break;
17691769
case BPF_HDR_START_NET:
1770-
ptr = net + offset;
1770+
start = skb_network_header(skb);
17711771
break;
17721772
default:
17731773
goto err_clear;
17741774
}
17751775

1776-
if (likely(ptr >= mac && ptr + len <= end)) {
1776+
ptr = start + offset;
1777+
1778+
if (likely(ptr + len <= end)) {
17771779
memcpy(to, ptr, len);
17781780
return 0;
17791781
}
@@ -4340,8 +4342,6 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname,
43404342
}
43414343
break;
43424344
case SO_BINDTODEVICE:
4343-
ret = -ENOPROTOOPT;
4344-
#ifdef CONFIG_NETDEVICES
43454345
optlen = min_t(long, optlen, IFNAMSIZ - 1);
43464346
strncpy(devname, optval, optlen);
43474347
devname[optlen] = 0;
@@ -4360,7 +4360,6 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname,
43604360
dev_put(dev);
43614361
}
43624362
ret = sock_bindtoindex(sk, ifindex, false);
4363-
#endif
43644363
break;
43654364
default:
43664365
ret = -EINVAL;

net/core/sock_map.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -424,10 +424,7 @@ static int sock_map_get_next_key(struct bpf_map *map, void *key, void *next)
424424
return 0;
425425
}
426426

427-
static bool sock_map_redirect_allowed(const struct sock *sk)
428-
{
429-
return sk->sk_state != TCP_LISTEN;
430-
}
427+
static bool sock_map_redirect_allowed(const struct sock *sk);
431428

432429
static int sock_map_update_common(struct bpf_map *map, u32 idx,
433430
struct sock *sk, u64 flags)
@@ -508,6 +505,11 @@ static bool sk_is_udp(const struct sock *sk)
508505
sk->sk_protocol == IPPROTO_UDP;
509506
}
510507

508+
static bool sock_map_redirect_allowed(const struct sock *sk)
509+
{
510+
return sk_is_tcp(sk) && sk->sk_state != TCP_LISTEN;
511+
}
512+
511513
static bool sock_map_sk_is_suitable(const struct sock *sk)
512514
{
513515
return sk_is_tcp(sk) || sk_is_udp(sk);
@@ -989,11 +991,15 @@ static struct bpf_map *sock_hash_alloc(union bpf_attr *attr)
989991
err = -EINVAL;
990992
goto free_htab;
991993
}
994+
err = bpf_map_charge_init(&htab->map.memory, cost);
995+
if (err)
996+
goto free_htab;
992997

993998
htab->buckets = bpf_map_area_alloc(htab->buckets_num *
994999
sizeof(struct bpf_htab_bucket),
9951000
htab->map.numa_node);
9961001
if (!htab->buckets) {
1002+
bpf_map_charge_finish(&htab->map.memory);
9971003
err = -ENOMEM;
9981004
goto free_htab;
9991005
}
@@ -1013,6 +1019,7 @@ static void sock_hash_free(struct bpf_map *map)
10131019
{
10141020
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
10151021
struct bpf_htab_bucket *bucket;
1022+
struct hlist_head unlink_list;
10161023
struct bpf_htab_elem *elem;
10171024
struct hlist_node *node;
10181025
int i;
@@ -1024,13 +1031,32 @@ static void sock_hash_free(struct bpf_map *map)
10241031
synchronize_rcu();
10251032
for (i = 0; i < htab->buckets_num; i++) {
10261033
bucket = sock_hash_select_bucket(htab, i);
1027-
hlist_for_each_entry_safe(elem, node, &bucket->head, node) {
1028-
hlist_del_rcu(&elem->node);
1034+
1035+
/* We are racing with sock_hash_delete_from_link to
1036+
* enter the spin-lock critical section. Every socket on
1037+
* the list is still linked to sockhash. Since link
1038+
* exists, psock exists and holds a ref to socket. That
1039+
* lets us to grab a socket ref too.
1040+
*/
1041+
raw_spin_lock_bh(&bucket->lock);
1042+
hlist_for_each_entry(elem, &bucket->head, node)
1043+
sock_hold(elem->sk);
1044+
hlist_move_list(&bucket->head, &unlink_list);
1045+
raw_spin_unlock_bh(&bucket->lock);
1046+
1047+
/* Process removed entries out of atomic context to
1048+
* block for socket lock before deleting the psock's
1049+
* link to sockhash.
1050+
*/
1051+
hlist_for_each_entry_safe(elem, node, &unlink_list, node) {
1052+
hlist_del(&elem->node);
10291053
lock_sock(elem->sk);
10301054
rcu_read_lock();
10311055
sock_map_unref(elem->sk, elem);
10321056
rcu_read_unlock();
10331057
release_sock(elem->sk);
1058+
sock_put(elem->sk);
1059+
sock_hash_free_elem(htab, elem);
10341060
}
10351061
}
10361062

net/ipv4/tcp_bpf.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ int __tcp_bpf_recvmsg(struct sock *sk, struct sk_psock *psock,
6464
} while (i != msg_rx->sg.end);
6565

6666
if (unlikely(peek)) {
67+
if (msg_rx == list_last_entry(&psock->ingress_msg,
68+
struct sk_msg, list))
69+
break;
6770
msg_rx = list_next_entry(msg_rx, list);
6871
continue;
6972
}
@@ -242,6 +245,9 @@ static int tcp_bpf_wait_data(struct sock *sk, struct sk_psock *psock,
242245
DEFINE_WAIT_FUNC(wait, woken_wake_function);
243246
int ret = 0;
244247

248+
if (sk->sk_shutdown & RCV_SHUTDOWN)
249+
return 1;
250+
245251
if (!timeo)
246252
return ret;
247253

net/xdp/xsk.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,8 @@ static int xsk_generic_xmit(struct sock *sk)
352352

353353
len = desc.len;
354354
skb = sock_alloc_send_skb(sk, len, 1, &err);
355-
if (unlikely(!skb)) {
356-
err = -EAGAIN;
355+
if (unlikely(!skb))
357356
goto out;
358-
}
359357

360358
skb_put(skb, len);
361359
addr = desc.addr;

scripts/link-vmlinux.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ gen_btf()
143143
fi
144144

145145
pahole_ver=$(${PAHOLE} --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/')
146-
if [ "${pahole_ver}" -lt "113" ]; then
147-
echo >&2 "BTF: ${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.13"
146+
if [ "${pahole_ver}" -lt "116" ]; then
147+
echo >&2 "BTF: ${1}: pahole version $(${PAHOLE} --version) is too old, need at least v1.16"
148148
return 1
149149
fi
150150

tools/bpf/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ include ../scripts/Makefile.include
33

44
prefix ?= /usr/local
55

6-
CC = gcc
76
LEX = flex
87
YACC = bison
98
MAKE = make

tools/bpf/bpftool/gen.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ static int codegen_datasecs(struct bpf_object *obj, const char *obj_name)
200200
return err;
201201
}
202202

203-
static int codegen(const char *template, ...)
203+
static void codegen(const char *template, ...)
204204
{
205205
const char *src, *end;
206206
int skip_tabs = 0, n;
@@ -211,7 +211,7 @@ static int codegen(const char *template, ...)
211211
n = strlen(template);
212212
s = malloc(n + 1);
213213
if (!s)
214-
return -ENOMEM;
214+
exit(-1);
215215
src = template;
216216
dst = s;
217217

@@ -224,7 +224,8 @@ static int codegen(const char *template, ...)
224224
} else {
225225
p_err("unrecognized character at pos %td in template '%s'",
226226
src - template - 1, template);
227-
return -EINVAL;
227+
free(s);
228+
exit(-1);
228229
}
229230
}
230231

@@ -234,7 +235,8 @@ static int codegen(const char *template, ...)
234235
if (*src != '\t') {
235236
p_err("not enough tabs at pos %td in template '%s'",
236237
src - template - 1, template);
237-
return -EINVAL;
238+
free(s);
239+
exit(-1);
238240
}
239241
}
240242
/* trim trailing whitespace */
@@ -255,7 +257,6 @@ static int codegen(const char *template, ...)
255257
va_end(args);
256258

257259
free(s);
258-
return n;
259260
}
260261

261262
static int do_skeleton(int argc, char **argv)

0 commit comments

Comments
 (0)