Skip to content

Commit 6436408

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2019-01-20 The following pull-request contains BPF updates for your *net* tree. The main changes are: 1) Fix a out-of-bounds access in __bpf_redirect_no_mac, from Willem. 2) Fix bpf_setsockopt to reset sock dst on SO_MARK changes, from Peter. 3) Fix map in map masking to prevent out-of-bounds access under speculative execution, from Daniel. 4) Fix bpf_setsockopt's SO_MAX_PACING_RATE to support TCP internal pacing, from Yuchung. 5) Fix json writer license in bpftool, from Thomas. 6) Fix AF_XDP to check if an actually queue exists during umem setup, from Krzysztof. 7) Several fixes to BPF stackmap's build id handling. Another fix for bpftool build to account for libbfd variations wrt linking requirements, from Stanislav. 8) Fix BPF samples build with clang by working around missing asm goto, from Yonghong. 9) Fix libbpf to retry program load on signal interrupt, from Lorenz. 10) Various minor compile warning fixes in BPF code, from Mathieu. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents df133f3 + e7c87bd commit 6436408

File tree

16 files changed

+1293
-36
lines changed

16 files changed

+1293
-36
lines changed

kernel/bpf/btf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ static const struct btf_kind_operations *btf_type_ops(const struct btf_type *t)
467467
return kind_ops[BTF_INFO_KIND(t->info)];
468468
}
469469

470-
bool btf_name_offset_valid(const struct btf *btf, u32 offset)
470+
static bool btf_name_offset_valid(const struct btf *btf, u32 offset)
471471
{
472472
return BTF_STR_OFFSET_VALID(offset) &&
473473
offset < btf->hdr.str_len;

kernel/bpf/cgroup.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,7 @@ cgroup_dev_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
718718
case BPF_FUNC_trace_printk:
719719
if (capable(CAP_SYS_ADMIN))
720720
return bpf_get_trace_printk_proto();
721+
/* fall through */
721722
default:
722723
return NULL;
723724
}

kernel/bpf/map_in_map.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd)
1313
{
1414
struct bpf_map *inner_map, *inner_map_meta;
15+
u32 inner_map_meta_size;
1516
struct fd f;
1617

1718
f = fdget(inner_map_ufd);
@@ -36,7 +37,12 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd)
3637
return ERR_PTR(-EINVAL);
3738
}
3839

39-
inner_map_meta = kzalloc(sizeof(*inner_map_meta), GFP_USER);
40+
inner_map_meta_size = sizeof(*inner_map_meta);
41+
/* In some cases verifier needs to access beyond just base map. */
42+
if (inner_map->ops == &array_map_ops)
43+
inner_map_meta_size = sizeof(struct bpf_array);
44+
45+
inner_map_meta = kzalloc(inner_map_meta_size, GFP_USER);
4046
if (!inner_map_meta) {
4147
fdput(f);
4248
return ERR_PTR(-ENOMEM);
@@ -46,9 +52,16 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd)
4652
inner_map_meta->key_size = inner_map->key_size;
4753
inner_map_meta->value_size = inner_map->value_size;
4854
inner_map_meta->map_flags = inner_map->map_flags;
49-
inner_map_meta->ops = inner_map->ops;
5055
inner_map_meta->max_entries = inner_map->max_entries;
5156

57+
/* Misc members not needed in bpf_map_meta_equal() check. */
58+
inner_map_meta->ops = inner_map->ops;
59+
if (inner_map->ops == &array_map_ops) {
60+
inner_map_meta->unpriv_array = inner_map->unpriv_array;
61+
container_of(inner_map_meta, struct bpf_array, map)->index_mask =
62+
container_of(inner_map, struct bpf_array, map)->index_mask;
63+
}
64+
5265
fdput(f);
5366
return inner_map_meta;
5467
}

kernel/bpf/stackmap.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,14 @@ static inline int stack_map_parse_build_id(void *page_addr,
180180

181181
if (nhdr->n_type == BPF_BUILD_ID &&
182182
nhdr->n_namesz == sizeof("GNU") &&
183-
nhdr->n_descsz == BPF_BUILD_ID_SIZE) {
183+
nhdr->n_descsz > 0 &&
184+
nhdr->n_descsz <= BPF_BUILD_ID_SIZE) {
184185
memcpy(build_id,
185186
note_start + note_offs +
186187
ALIGN(sizeof("GNU"), 4) + sizeof(Elf32_Nhdr),
187-
BPF_BUILD_ID_SIZE);
188+
nhdr->n_descsz);
189+
memset(build_id + nhdr->n_descsz, 0,
190+
BPF_BUILD_ID_SIZE - nhdr->n_descsz);
188191
return 0;
189192
}
190193
new_offs = note_offs + sizeof(Elf32_Nhdr) +
@@ -311,6 +314,7 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
311314
for (i = 0; i < trace_nr; i++) {
312315
id_offs[i].status = BPF_STACK_BUILD_ID_IP;
313316
id_offs[i].ip = ips[i];
317+
memset(id_offs[i].build_id, 0, BPF_BUILD_ID_SIZE);
314318
}
315319
return;
316320
}
@@ -321,6 +325,7 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
321325
/* per entry fall back to ips */
322326
id_offs[i].status = BPF_STACK_BUILD_ID_IP;
323327
id_offs[i].ip = ips[i];
328+
memset(id_offs[i].build_id, 0, BPF_BUILD_ID_SIZE);
324329
continue;
325330
}
326331
id_offs[i].offset = (vma->vm_pgoff << PAGE_SHIFT) + ips[i]

net/core/filter.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,18 +2020,19 @@ static inline int __bpf_tx_skb(struct net_device *dev, struct sk_buff *skb)
20202020
static int __bpf_redirect_no_mac(struct sk_buff *skb, struct net_device *dev,
20212021
u32 flags)
20222022
{
2023-
/* skb->mac_len is not set on normal egress */
2024-
unsigned int mlen = skb->network_header - skb->mac_header;
2023+
unsigned int mlen = skb_network_offset(skb);
20252024

2026-
__skb_pull(skb, mlen);
2025+
if (mlen) {
2026+
__skb_pull(skb, mlen);
20272027

2028-
/* At ingress, the mac header has already been pulled once.
2029-
* At egress, skb_pospull_rcsum has to be done in case that
2030-
* the skb is originated from ingress (i.e. a forwarded skb)
2031-
* to ensure that rcsum starts at net header.
2032-
*/
2033-
if (!skb_at_tc_ingress(skb))
2034-
skb_postpull_rcsum(skb, skb_mac_header(skb), mlen);
2028+
/* At ingress, the mac header has already been pulled once.
2029+
* At egress, skb_pospull_rcsum has to be done in case that
2030+
* the skb is originated from ingress (i.e. a forwarded skb)
2031+
* to ensure that rcsum starts at net header.
2032+
*/
2033+
if (!skb_at_tc_ingress(skb))
2034+
skb_postpull_rcsum(skb, skb_mac_header(skb), mlen);
2035+
}
20352036
skb_pop_mac_header(skb);
20362037
skb_reset_mac_len(skb);
20372038
return flags & BPF_F_INGRESS ?
@@ -4119,6 +4120,10 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock,
41194120
sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF);
41204121
break;
41214122
case SO_MAX_PACING_RATE: /* 32bit version */
4123+
if (val != ~0U)
4124+
cmpxchg(&sk->sk_pacing_status,
4125+
SK_PACING_NONE,
4126+
SK_PACING_NEEDED);
41224127
sk->sk_max_pacing_rate = (val == ~0U) ? ~0UL : val;
41234128
sk->sk_pacing_rate = min(sk->sk_pacing_rate,
41244129
sk->sk_max_pacing_rate);
@@ -4132,7 +4137,10 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock,
41324137
sk->sk_rcvlowat = val ? : 1;
41334138
break;
41344139
case SO_MARK:
4135-
sk->sk_mark = val;
4140+
if (sk->sk_mark != val) {
4141+
sk->sk_mark = val;
4142+
sk_dst_reset(sk);
4143+
}
41364144
break;
41374145
default:
41384146
ret = -EINVAL;
@@ -5309,7 +5317,7 @@ bpf_base_func_proto(enum bpf_func_id func_id)
53095317
case BPF_FUNC_trace_printk:
53105318
if (capable(CAP_SYS_ADMIN))
53115319
return bpf_get_trace_printk_proto();
5312-
/* else: fall through */
5320+
/* else, fall through */
53135321
default:
53145322
return NULL;
53155323
}

net/core/lwt_bpf.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ static int run_lwt_bpf(struct sk_buff *skb, struct bpf_lwt_prog *lwt,
6363
lwt->name ? : "<unknown>");
6464
ret = BPF_OK;
6565
} else {
66+
skb_reset_mac_header(skb);
6667
ret = skb_do_redirect(skb);
6768
if (ret == 0)
6869
ret = BPF_REDIRECT;

net/xdp/xdp_umem.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,20 @@ void xdp_del_sk_umem(struct xdp_umem *umem, struct xdp_sock *xs)
4141
* not know if the device has more tx queues than rx, or the opposite.
4242
* This might also change during run time.
4343
*/
44-
static void xdp_reg_umem_at_qid(struct net_device *dev, struct xdp_umem *umem,
45-
u16 queue_id)
44+
static int xdp_reg_umem_at_qid(struct net_device *dev, struct xdp_umem *umem,
45+
u16 queue_id)
4646
{
47+
if (queue_id >= max_t(unsigned int,
48+
dev->real_num_rx_queues,
49+
dev->real_num_tx_queues))
50+
return -EINVAL;
51+
4752
if (queue_id < dev->real_num_rx_queues)
4853
dev->_rx[queue_id].umem = umem;
4954
if (queue_id < dev->real_num_tx_queues)
5055
dev->_tx[queue_id].umem = umem;
56+
57+
return 0;
5158
}
5259

5360
struct xdp_umem *xdp_get_umem_from_qid(struct net_device *dev,
@@ -88,7 +95,10 @@ int xdp_umem_assign_dev(struct xdp_umem *umem, struct net_device *dev,
8895
goto out_rtnl_unlock;
8996
}
9097

91-
xdp_reg_umem_at_qid(dev, umem, queue_id);
98+
err = xdp_reg_umem_at_qid(dev, umem, queue_id);
99+
if (err)
100+
goto out_rtnl_unlock;
101+
92102
umem->dev = dev;
93103
umem->queue_id = queue_id;
94104
if (force_copy)

samples/bpf/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ $(obj)/%.o: $(src)/%.c
279279
-Wno-gnu-variable-sized-type-not-at-end \
280280
-Wno-address-of-packed-member -Wno-tautological-compare \
281281
-Wno-unknown-warning-option $(CLANG_ARCH_ARGS) \
282+
-I$(srctree)/samples/bpf/ -include asm_goto_workaround.h \
282283
-O2 -emit-llvm -c $< -o -| $(LLC) -march=bpf $(LLC_FLAGS) -filetype=obj -o $@
283284
ifeq ($(DWARF2BTF),y)
284285
$(BTF_PAHOLE) -J $@

samples/bpf/asm_goto_workaround.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/* Copyright (c) 2019 Facebook */
3+
#ifndef __ASM_GOTO_WORKAROUND_H
4+
#define __ASM_GOTO_WORKAROUND_H
5+
6+
/* this will bring in asm_volatile_goto macro definition
7+
* if enabled by compiler and config options.
8+
*/
9+
#include <linux/types.h>
10+
11+
#ifdef asm_volatile_goto
12+
#undef asm_volatile_goto
13+
#define asm_volatile_goto(x...) asm volatile("invalid use of asm_volatile_goto")
14+
#endif
15+
16+
#endif

tools/bpf/bpftool/Makefile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,16 @@ BFD_SRCS = jit_disasm.c
9393
SRCS = $(filter-out $(BFD_SRCS),$(wildcard *.c))
9494

9595
ifeq ($(feature-libbfd),1)
96+
LIBS += -lbfd -ldl -lopcodes
97+
else ifeq ($(feature-libbfd-liberty),1)
98+
LIBS += -lbfd -ldl -lopcodes -liberty
99+
else ifeq ($(feature-libbfd-liberty-z),1)
100+
LIBS += -lbfd -ldl -lopcodes -liberty -lz
101+
endif
102+
103+
ifneq ($(filter -lbfd,$(LIBS)),)
96104
CFLAGS += -DHAVE_LIBBFD_SUPPORT
97105
SRCS += $(BFD_SRCS)
98-
LIBS += -lbfd -lopcodes
99106
endif
100107

101108
OBJS = $(patsubst %.c,$(OUTPUT)%.o,$(SRCS)) $(OUTPUT)disasm.o

tools/bpf/bpftool/json_writer.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
1+
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
22
/*
33
* Simple streaming JSON writer
44
*
55
* This takes care of the annoying bits of JSON syntax like the commas
66
* after elements
77
*
8-
* This program is free software; you can redistribute it and/or
9-
* modify it under the terms of the GNU General Public License
10-
* as published by the Free Software Foundation; either version
11-
* 2 of the License, or (at your option) any later version.
12-
*
138
* Authors: Stephen Hemminger <stephen@networkplumber.org>
149
*/
1510

tools/bpf/bpftool/json_writer.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@
55
* This takes care of the annoying bits of JSON syntax like the commas
66
* after elements
77
*
8-
* This program is free software; you can redistribute it and/or
9-
* modify it under the terms of the GNU General Public License
10-
* as published by the Free Software Foundation; either version
11-
* 2 of the License, or (at your option) any later version.
12-
*
138
* Authors: Stephen Hemminger <stephen@networkplumber.org>
149
*/
1510

0 commit comments

Comments
 (0)