Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c849eb0

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2018-07-13 The following pull-request contains BPF updates for your *net* tree. The main changes are: 1) Fix AF_XDP TX error reporting before final kernel release such that it becomes consistent between copy mode and zero-copy, from Magnus. 2) Fix three different syzkaller reported issues: oob due to ld_abs rewrite with too large offset, another oob in l3 based skb test run and a bug leaving mangled prog in subprog JITing error path, from Daniel. 3) Fix BTF handling for bitfield extraction on big endian, from Okash. 4) Fix a missing linux/errno.h include in cgroup/BPF found by kbuild bot, from Roman. 5) Fix xdp2skb_meta.sh sample by using just command names instead of absolute paths for tc and ip and allow them to be redefined, from Taeung. 6) Fix availability probing for BPF seg6 helpers before final kernel ships so they can be detected at prog load time, from Mathieu. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents e78bfb0 + 5e3e6e8 commit c849eb0

8 files changed

Lines changed: 88 additions & 59 deletions

File tree

include/linux/bpf-cgroup.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#ifndef _BPF_CGROUP_H
33
#define _BPF_CGROUP_H
44

5+
#include <linux/errno.h>
56
#include <linux/jump_label.h>
67
#include <uapi/linux/bpf.h>
78

kernel/bpf/btf.c

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -991,38 +991,34 @@ static void btf_int_bits_seq_show(const struct btf *btf,
991991
void *data, u8 bits_offset,
992992
struct seq_file *m)
993993
{
994+
u16 left_shift_bits, right_shift_bits;
994995
u32 int_data = btf_type_int(t);
995996
u16 nr_bits = BTF_INT_BITS(int_data);
996997
u16 total_bits_offset;
997998
u16 nr_copy_bytes;
998999
u16 nr_copy_bits;
999-
u8 nr_upper_bits;
1000-
union {
1001-
u64 u64_num;
1002-
u8 u8_nums[8];
1003-
} print_num;
1000+
u64 print_num;
10041001

10051002
total_bits_offset = bits_offset + BTF_INT_OFFSET(int_data);
10061003
data += BITS_ROUNDDOWN_BYTES(total_bits_offset);
10071004
bits_offset = BITS_PER_BYTE_MASKED(total_bits_offset);
10081005
nr_copy_bits = nr_bits + bits_offset;
10091006
nr_copy_bytes = BITS_ROUNDUP_BYTES(nr_copy_bits);
10101007

1011-
print_num.u64_num = 0;
1012-
memcpy(&print_num.u64_num, data, nr_copy_bytes);
1008+
print_num = 0;
1009+
memcpy(&print_num, data, nr_copy_bytes);
10131010

1014-
/* Ditch the higher order bits */
1015-
nr_upper_bits = BITS_PER_BYTE_MASKED(nr_copy_bits);
1016-
if (nr_upper_bits) {
1017-
/* We need to mask out some bits of the upper byte. */
1018-
u8 mask = (1 << nr_upper_bits) - 1;
1011+
#ifdef __BIG_ENDIAN_BITFIELD
1012+
left_shift_bits = bits_offset;
1013+
#else
1014+
left_shift_bits = BITS_PER_U64 - nr_copy_bits;
1015+
#endif
1016+
right_shift_bits = BITS_PER_U64 - nr_bits;
10191017

1020-
print_num.u8_nums[nr_copy_bytes - 1] &= mask;
1021-
}
1022-
1023-
print_num.u64_num >>= bits_offset;
1018+
print_num <<= left_shift_bits;
1019+
print_num >>= right_shift_bits;
10241020

1025-
seq_printf(m, "0x%llx", print_num.u64_num);
1021+
seq_printf(m, "0x%llx", print_num);
10261022
}
10271023

10281024
static void btf_int_seq_show(const struct btf *btf, const struct btf_type *t,

kernel/bpf/verifier.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5430,6 +5430,10 @@ static int jit_subprogs(struct bpf_verifier_env *env)
54305430
if (insn->code != (BPF_JMP | BPF_CALL) ||
54315431
insn->src_reg != BPF_PSEUDO_CALL)
54325432
continue;
5433+
/* Upon error here we cannot fall back to interpreter but
5434+
* need a hard reject of the program. Thus -EFAULT is
5435+
* propagated in any case.
5436+
*/
54335437
subprog = find_subprog(env, i + insn->imm + 1);
54345438
if (subprog < 0) {
54355439
WARN_ONCE(1, "verifier bug. No program starts at insn %d\n",
@@ -5450,7 +5454,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)
54505454

54515455
func = kcalloc(env->subprog_cnt, sizeof(prog), GFP_KERNEL);
54525456
if (!func)
5453-
return -ENOMEM;
5457+
goto out_undo_insn;
54545458

54555459
for (i = 0; i < env->subprog_cnt; i++) {
54565460
subprog_start = subprog_end;
@@ -5515,7 +5519,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)
55155519
tmp = bpf_int_jit_compile(func[i]);
55165520
if (tmp != func[i] || func[i]->bpf_func != old_bpf_func) {
55175521
verbose(env, "JIT doesn't support bpf-to-bpf calls\n");
5518-
err = -EFAULT;
5522+
err = -ENOTSUPP;
55195523
goto out_free;
55205524
}
55215525
cond_resched();
@@ -5552,6 +5556,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)
55525556
if (func[i])
55535557
bpf_jit_free(func[i]);
55545558
kfree(func);
5559+
out_undo_insn:
55555560
/* cleanup main prog to be interpreted */
55565561
prog->jit_requested = 0;
55575562
for (i = 0, insn = prog->insnsi; i < prog->len; i++, insn++) {
@@ -5578,6 +5583,8 @@ static int fixup_call_args(struct bpf_verifier_env *env)
55785583
err = jit_subprogs(env);
55795584
if (err == 0)
55805585
return 0;
5586+
if (err == -EFAULT)
5587+
return err;
55815588
}
55825589
#ifndef CONFIG_BPF_JIT_ALWAYS_ON
55835590
for (i = 0; i < prog->len; i++, insn++) {

net/bpf/test_run.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
9696
u32 size = kattr->test.data_size_in;
9797
u32 repeat = kattr->test.repeat;
9898
u32 retval, duration;
99+
int hh_len = ETH_HLEN;
99100
struct sk_buff *skb;
100101
void *data;
101102
int ret;
@@ -131,12 +132,22 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
131132
skb_reset_network_header(skb);
132133

133134
if (is_l2)
134-
__skb_push(skb, ETH_HLEN);
135+
__skb_push(skb, hh_len);
135136
if (is_direct_pkt_access)
136137
bpf_compute_data_pointers(skb);
137138
retval = bpf_test_run(prog, skb, repeat, &duration);
138-
if (!is_l2)
139-
__skb_push(skb, ETH_HLEN);
139+
if (!is_l2) {
140+
if (skb_headroom(skb) < hh_len) {
141+
int nhead = HH_DATA_ALIGN(hh_len - skb_headroom(skb));
142+
143+
if (pskb_expand_head(skb, nhead, 0, GFP_USER)) {
144+
kfree_skb(skb);
145+
return -ENOMEM;
146+
}
147+
}
148+
memset(__skb_push(skb, hh_len), 0, hh_len);
149+
}
150+
140151
size = skb->len;
141152
/* bpf program can never convert linear skb to non-linear */
142153
if (WARN_ON_ONCE(skb_is_nonlinear(skb)))

net/core/filter.c

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -459,11 +459,21 @@ static bool convert_bpf_ld_abs(struct sock_filter *fp, struct bpf_insn **insnp)
459459
(!unaligned_ok && offset >= 0 &&
460460
offset + ip_align >= 0 &&
461461
offset + ip_align % size == 0))) {
462+
bool ldx_off_ok = offset <= S16_MAX;
463+
462464
*insn++ = BPF_MOV64_REG(BPF_REG_TMP, BPF_REG_H);
463465
*insn++ = BPF_ALU64_IMM(BPF_SUB, BPF_REG_TMP, offset);
464-
*insn++ = BPF_JMP_IMM(BPF_JSLT, BPF_REG_TMP, size, 2 + endian);
465-
*insn++ = BPF_LDX_MEM(BPF_SIZE(fp->code), BPF_REG_A, BPF_REG_D,
466-
offset);
466+
*insn++ = BPF_JMP_IMM(BPF_JSLT, BPF_REG_TMP,
467+
size, 2 + endian + (!ldx_off_ok * 2));
468+
if (ldx_off_ok) {
469+
*insn++ = BPF_LDX_MEM(BPF_SIZE(fp->code), BPF_REG_A,
470+
BPF_REG_D, offset);
471+
} else {
472+
*insn++ = BPF_MOV64_REG(BPF_REG_TMP, BPF_REG_D);
473+
*insn++ = BPF_ALU64_IMM(BPF_ADD, BPF_REG_TMP, offset);
474+
*insn++ = BPF_LDX_MEM(BPF_SIZE(fp->code), BPF_REG_A,
475+
BPF_REG_TMP, 0);
476+
}
467477
if (endian)
468478
*insn++ = BPF_ENDIAN(BPF_FROM_BE, BPF_REG_A, size * 8);
469479
*insn++ = BPF_JMP_A(8);
@@ -4526,10 +4536,10 @@ static const struct bpf_func_proto bpf_lwt_push_encap_proto = {
45264536
.arg4_type = ARG_CONST_SIZE
45274537
};
45284538

4539+
#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
45294540
BPF_CALL_4(bpf_lwt_seg6_store_bytes, struct sk_buff *, skb, u32, offset,
45304541
const void *, from, u32, len)
45314542
{
4532-
#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
45334543
struct seg6_bpf_srh_state *srh_state =
45344544
this_cpu_ptr(&seg6_bpf_srh_states);
45354545
void *srh_tlvs, *srh_end, *ptr;
@@ -4555,9 +4565,6 @@ BPF_CALL_4(bpf_lwt_seg6_store_bytes, struct sk_buff *, skb, u32, offset,
45554565

45564566
memcpy(skb->data + offset, from, len);
45574567
return 0;
4558-
#else /* CONFIG_IPV6_SEG6_BPF */
4559-
return -EOPNOTSUPP;
4560-
#endif
45614568
}
45624569

45634570
static const struct bpf_func_proto bpf_lwt_seg6_store_bytes_proto = {
@@ -4573,7 +4580,6 @@ static const struct bpf_func_proto bpf_lwt_seg6_store_bytes_proto = {
45734580
BPF_CALL_4(bpf_lwt_seg6_action, struct sk_buff *, skb,
45744581
u32, action, void *, param, u32, param_len)
45754582
{
4576-
#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
45774583
struct seg6_bpf_srh_state *srh_state =
45784584
this_cpu_ptr(&seg6_bpf_srh_states);
45794585
struct ipv6_sr_hdr *srh;
@@ -4621,9 +4627,6 @@ BPF_CALL_4(bpf_lwt_seg6_action, struct sk_buff *, skb,
46214627
default:
46224628
return -EINVAL;
46234629
}
4624-
#else /* CONFIG_IPV6_SEG6_BPF */
4625-
return -EOPNOTSUPP;
4626-
#endif
46274630
}
46284631

46294632
static const struct bpf_func_proto bpf_lwt_seg6_action_proto = {
@@ -4639,7 +4642,6 @@ static const struct bpf_func_proto bpf_lwt_seg6_action_proto = {
46394642
BPF_CALL_3(bpf_lwt_seg6_adjust_srh, struct sk_buff *, skb, u32, offset,
46404643
s32, len)
46414644
{
4642-
#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
46434645
struct seg6_bpf_srh_state *srh_state =
46444646
this_cpu_ptr(&seg6_bpf_srh_states);
46454647
void *srh_end, *srh_tlvs, *ptr;
@@ -4683,9 +4685,6 @@ BPF_CALL_3(bpf_lwt_seg6_adjust_srh, struct sk_buff *, skb, u32, offset,
46834685
srh_state->hdrlen += len;
46844686
srh_state->valid = 0;
46854687
return 0;
4686-
#else /* CONFIG_IPV6_SEG6_BPF */
4687-
return -EOPNOTSUPP;
4688-
#endif
46894688
}
46904689

46914690
static const struct bpf_func_proto bpf_lwt_seg6_adjust_srh_proto = {
@@ -4696,6 +4695,7 @@ static const struct bpf_func_proto bpf_lwt_seg6_adjust_srh_proto = {
46964695
.arg2_type = ARG_ANYTHING,
46974696
.arg3_type = ARG_ANYTHING,
46984697
};
4698+
#endif /* CONFIG_IPV6_SEG6_BPF */
46994699

47004700
bool bpf_helper_changes_pkt_data(void *func)
47014701
{
@@ -4717,11 +4717,12 @@ bool bpf_helper_changes_pkt_data(void *func)
47174717
func == bpf_xdp_adjust_meta ||
47184718
func == bpf_msg_pull_data ||
47194719
func == bpf_xdp_adjust_tail ||
4720-
func == bpf_lwt_push_encap ||
4720+
#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
47214721
func == bpf_lwt_seg6_store_bytes ||
47224722
func == bpf_lwt_seg6_adjust_srh ||
4723-
func == bpf_lwt_seg6_action
4724-
)
4723+
func == bpf_lwt_seg6_action ||
4724+
#endif
4725+
func == bpf_lwt_push_encap)
47254726
return true;
47264727

47274728
return false;
@@ -5056,12 +5057,14 @@ static const struct bpf_func_proto *
50565057
lwt_seg6local_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
50575058
{
50585059
switch (func_id) {
5060+
#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
50595061
case BPF_FUNC_lwt_seg6_store_bytes:
50605062
return &bpf_lwt_seg6_store_bytes_proto;
50615063
case BPF_FUNC_lwt_seg6_action:
50625064
return &bpf_lwt_seg6_action_proto;
50635065
case BPF_FUNC_lwt_seg6_adjust_srh:
50645066
return &bpf_lwt_seg6_adjust_srh_proto;
5067+
#endif
50655068
default:
50665069
return lwt_out_func_proto(func_id, prog);
50675070
}

net/xdp/xsk.c

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,6 @@ static int xsk_generic_xmit(struct sock *sk, struct msghdr *m,
218218
struct sk_buff *skb;
219219
int err = 0;
220220

221-
if (unlikely(!xs->tx))
222-
return -ENOBUFS;
223-
224221
mutex_lock(&xs->mutex);
225222

226223
while (xskq_peek_desc(xs->tx, &desc)) {
@@ -233,22 +230,13 @@ static int xsk_generic_xmit(struct sock *sk, struct msghdr *m,
233230
goto out;
234231
}
235232

236-
if (xskq_reserve_addr(xs->umem->cq)) {
237-
err = -EAGAIN;
233+
if (xskq_reserve_addr(xs->umem->cq))
238234
goto out;
239-
}
240235

241-
len = desc.len;
242-
if (unlikely(len > xs->dev->mtu)) {
243-
err = -EMSGSIZE;
236+
if (xs->queue_id >= xs->dev->real_num_tx_queues)
244237
goto out;
245-
}
246-
247-
if (xs->queue_id >= xs->dev->real_num_tx_queues) {
248-
err = -ENXIO;
249-
goto out;
250-
}
251238

239+
len = desc.len;
252240
skb = sock_alloc_send_skb(sk, len, 1, &err);
253241
if (unlikely(!skb)) {
254242
err = -EAGAIN;
@@ -300,6 +288,8 @@ static int xsk_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len)
300288
return -ENXIO;
301289
if (unlikely(!(xs->dev->flags & IFF_UP)))
302290
return -ENETDOWN;
291+
if (unlikely(!xs->tx))
292+
return -ENOBUFS;
303293
if (need_wait)
304294
return -EOPNOTSUPP;
305295

samples/bpf/xdp2skb_meta.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
BPF_FILE=xdp2skb_meta_kern.o
1717
DIR=$(dirname $0)
1818

19-
export TC=/usr/sbin/tc
20-
export IP=/usr/sbin/ip
19+
[ -z "$TC" ] && TC=tc
20+
[ -z "$IP" ] && IP=ip
2121

2222
function usage() {
2323
echo ""
@@ -53,7 +53,7 @@ function _call_cmd() {
5353
local allow_fail="$2"
5454
shift 2
5555
if [[ -n "$VERBOSE" ]]; then
56-
echo "$(basename $cmd) $@"
56+
echo "$cmd $@"
5757
fi
5858
if [[ -n "$DRYRUN" ]]; then
5959
return

tools/testing/selftests/bpf/test_verifier.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4974,6 +4974,24 @@ static struct bpf_test tests[] = {
49744974
.result = ACCEPT,
49754975
.prog_type = BPF_PROG_TYPE_LWT_XMIT,
49764976
},
4977+
{
4978+
"make headroom for LWT_XMIT",
4979+
.insns = {
4980+
BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
4981+
BPF_MOV64_IMM(BPF_REG_2, 34),
4982+
BPF_MOV64_IMM(BPF_REG_3, 0),
4983+
BPF_EMIT_CALL(BPF_FUNC_skb_change_head),
4984+
/* split for s390 to succeed */
4985+
BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
4986+
BPF_MOV64_IMM(BPF_REG_2, 42),
4987+
BPF_MOV64_IMM(BPF_REG_3, 0),
4988+
BPF_EMIT_CALL(BPF_FUNC_skb_change_head),
4989+
BPF_MOV64_IMM(BPF_REG_0, 0),
4990+
BPF_EXIT_INSN(),
4991+
},
4992+
.result = ACCEPT,
4993+
.prog_type = BPF_PROG_TYPE_LWT_XMIT,
4994+
},
49774995
{
49784996
"invalid access of tc_classid for LWT_IN",
49794997
.insns = {
@@ -12554,8 +12572,11 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
1255412572
}
1255512573

1255612574
if (fd_prog >= 0) {
12575+
__u8 tmp[TEST_DATA_LEN << 2];
12576+
__u32 size_tmp = sizeof(tmp);
12577+
1255712578
err = bpf_prog_test_run(fd_prog, 1, test->data,
12558-
sizeof(test->data), NULL, NULL,
12579+
sizeof(test->data), tmp, &size_tmp,
1255912580
&retval, NULL);
1256012581
if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
1256112582
printf("Unexpected bpf_prog_test_run error\n");

0 commit comments

Comments
 (0)