aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-07-13 17:31:47 -0400
committerDavid S. Miller <davem@davemloft.net>2018-07-13 17:31:47 -0400
commitc849eb0d1e75215fc0c2ecbb8706f66b169c7710 (patch)
tree95580227d41b854d7ecb8c09f1393b425011b83c
parente78bfb0751d4e312699106ba7efbed2bab1a53ca (diff)
parent5e3e6e834eacfe8f1071540df7831cbb3e8ca0d3 (diff)
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 <davem@davemloft.net>
-rw-r--r--include/linux/bpf-cgroup.h1
-rw-r--r--kernel/bpf/btf.c30
-rw-r--r--kernel/bpf/verifier.c11
-rw-r--r--net/bpf/test_run.c17
-rw-r--r--net/core/filter.c39
-rw-r--r--net/xdp/xsk.c20
-rwxr-xr-xsamples/bpf/xdp2skb_meta.sh6
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c23
8 files changed, 88 insertions, 59 deletions
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 79795c5fa7c3..d50c2f0a655a 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -2,6 +2,7 @@
2#ifndef _BPF_CGROUP_H 2#ifndef _BPF_CGROUP_H
3#define _BPF_CGROUP_H 3#define _BPF_CGROUP_H
4 4
5#include <linux/errno.h>
5#include <linux/jump_label.h> 6#include <linux/jump_label.h>
6#include <uapi/linux/bpf.h> 7#include <uapi/linux/bpf.h>
7 8
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 2d49d18b793a..e016ac3afa24 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -991,16 +991,13 @@ static void btf_int_bits_seq_show(const struct btf *btf,
991 void *data, u8 bits_offset, 991 void *data, u8 bits_offset,
992 struct seq_file *m) 992 struct seq_file *m)
993{ 993{
994 u16 left_shift_bits, right_shift_bits;
994 u32 int_data = btf_type_int(t); 995 u32 int_data = btf_type_int(t);
995 u16 nr_bits = BTF_INT_BITS(int_data); 996 u16 nr_bits = BTF_INT_BITS(int_data);
996 u16 total_bits_offset; 997 u16 total_bits_offset;
997 u16 nr_copy_bytes; 998 u16 nr_copy_bytes;
998 u16 nr_copy_bits; 999 u16 nr_copy_bits;
999 u8 nr_upper_bits; 1000 u64 print_num;
1000 union {
1001 u64 u64_num;
1002 u8 u8_nums[8];
1003 } print_num;
1004 1001
1005 total_bits_offset = bits_offset + BTF_INT_OFFSET(int_data); 1002 total_bits_offset = bits_offset + BTF_INT_OFFSET(int_data);
1006 data += BITS_ROUNDDOWN_BYTES(total_bits_offset); 1003 data += BITS_ROUNDDOWN_BYTES(total_bits_offset);
@@ -1008,21 +1005,20 @@ static void btf_int_bits_seq_show(const struct btf *btf,
1008 nr_copy_bits = nr_bits + bits_offset; 1005 nr_copy_bits = nr_bits + bits_offset;
1009 nr_copy_bytes = BITS_ROUNDUP_BYTES(nr_copy_bits); 1006 nr_copy_bytes = BITS_ROUNDUP_BYTES(nr_copy_bits);
1010 1007
1011 print_num.u64_num = 0; 1008 print_num = 0;
1012 memcpy(&print_num.u64_num, data, nr_copy_bytes); 1009 memcpy(&print_num, data, nr_copy_bytes);
1013 1010
1014 /* Ditch the higher order bits */ 1011#ifdef __BIG_ENDIAN_BITFIELD
1015 nr_upper_bits = BITS_PER_BYTE_MASKED(nr_copy_bits); 1012 left_shift_bits = bits_offset;
1016 if (nr_upper_bits) { 1013#else
1017 /* We need to mask out some bits of the upper byte. */ 1014 left_shift_bits = BITS_PER_U64 - nr_copy_bits;
1018 u8 mask = (1 << nr_upper_bits) - 1; 1015#endif
1016 right_shift_bits = BITS_PER_U64 - nr_bits;
1019 1017
1020 print_num.u8_nums[nr_copy_bytes - 1] &= mask; 1018 print_num <<= left_shift_bits;
1021 } 1019 print_num >>= right_shift_bits;
1022
1023 print_num.u64_num >>= bits_offset;
1024 1020
1025 seq_printf(m, "0x%llx", print_num.u64_num); 1021 seq_printf(m, "0x%llx", print_num);
1026} 1022}
1027 1023
1028static void btf_int_seq_show(const struct btf *btf, const struct btf_type *t, 1024static void btf_int_seq_show(const struct btf *btf, const struct btf_type *t,
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 9e2bf834f13a..63aaac52a265 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -5430,6 +5430,10 @@ static int jit_subprogs(struct bpf_verifier_env *env)
5430 if (insn->code != (BPF_JMP | BPF_CALL) || 5430 if (insn->code != (BPF_JMP | BPF_CALL) ||
5431 insn->src_reg != BPF_PSEUDO_CALL) 5431 insn->src_reg != BPF_PSEUDO_CALL)
5432 continue; 5432 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 */
5433 subprog = find_subprog(env, i + insn->imm + 1); 5437 subprog = find_subprog(env, i + insn->imm + 1);
5434 if (subprog < 0) { 5438 if (subprog < 0) {
5435 WARN_ONCE(1, "verifier bug. No program starts at insn %d\n", 5439 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)
5450 5454
5451 func = kcalloc(env->subprog_cnt, sizeof(prog), GFP_KERNEL); 5455 func = kcalloc(env->subprog_cnt, sizeof(prog), GFP_KERNEL);
5452 if (!func) 5456 if (!func)
5453 return -ENOMEM; 5457 goto out_undo_insn;
5454 5458
5455 for (i = 0; i < env->subprog_cnt; i++) { 5459 for (i = 0; i < env->subprog_cnt; i++) {
5456 subprog_start = subprog_end; 5460 subprog_start = subprog_end;
@@ -5515,7 +5519,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)
5515 tmp = bpf_int_jit_compile(func[i]); 5519 tmp = bpf_int_jit_compile(func[i]);
5516 if (tmp != func[i] || func[i]->bpf_func != old_bpf_func) { 5520 if (tmp != func[i] || func[i]->bpf_func != old_bpf_func) {
5517 verbose(env, "JIT doesn't support bpf-to-bpf calls\n"); 5521 verbose(env, "JIT doesn't support bpf-to-bpf calls\n");
5518 err = -EFAULT; 5522 err = -ENOTSUPP;
5519 goto out_free; 5523 goto out_free;
5520 } 5524 }
5521 cond_resched(); 5525 cond_resched();
@@ -5552,6 +5556,7 @@ out_free:
5552 if (func[i]) 5556 if (func[i])
5553 bpf_jit_free(func[i]); 5557 bpf_jit_free(func[i]);
5554 kfree(func); 5558 kfree(func);
5559out_undo_insn:
5555 /* cleanup main prog to be interpreted */ 5560 /* cleanup main prog to be interpreted */
5556 prog->jit_requested = 0; 5561 prog->jit_requested = 0;
5557 for (i = 0, insn = prog->insnsi; i < prog->len; i++, insn++) { 5562 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)
5578 err = jit_subprogs(env); 5583 err = jit_subprogs(env);
5579 if (err == 0) 5584 if (err == 0)
5580 return 0; 5585 return 0;
5586 if (err == -EFAULT)
5587 return err;
5581 } 5588 }
5582#ifndef CONFIG_BPF_JIT_ALWAYS_ON 5589#ifndef CONFIG_BPF_JIT_ALWAYS_ON
5583 for (i = 0; i < prog->len; i++, insn++) { 5590 for (i = 0; i < prog->len; i++, insn++) {
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index 68c3578343b4..22a78eedf4b1 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -96,6 +96,7 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
96 u32 size = kattr->test.data_size_in; 96 u32 size = kattr->test.data_size_in;
97 u32 repeat = kattr->test.repeat; 97 u32 repeat = kattr->test.repeat;
98 u32 retval, duration; 98 u32 retval, duration;
99 int hh_len = ETH_HLEN;
99 struct sk_buff *skb; 100 struct sk_buff *skb;
100 void *data; 101 void *data;
101 int ret; 102 int ret;
@@ -131,12 +132,22 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
131 skb_reset_network_header(skb); 132 skb_reset_network_header(skb);
132 133
133 if (is_l2) 134 if (is_l2)
134 __skb_push(skb, ETH_HLEN); 135 __skb_push(skb, hh_len);
135 if (is_direct_pkt_access) 136 if (is_direct_pkt_access)
136 bpf_compute_data_pointers(skb); 137 bpf_compute_data_pointers(skb);
137 retval = bpf_test_run(prog, skb, repeat, &duration); 138 retval = bpf_test_run(prog, skb, repeat, &duration);
138 if (!is_l2) 139 if (!is_l2) {
139 __skb_push(skb, ETH_HLEN); 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
140 size = skb->len; 151 size = skb->len;
141 /* bpf program can never convert linear skb to non-linear */ 152 /* bpf program can never convert linear skb to non-linear */
142 if (WARN_ON_ONCE(skb_is_nonlinear(skb))) 153 if (WARN_ON_ONCE(skb_is_nonlinear(skb)))
diff --git a/net/core/filter.c b/net/core/filter.c
index 5fa66a33927f..06da770f543f 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -459,11 +459,21 @@ static bool convert_bpf_ld_abs(struct sock_filter *fp, struct bpf_insn **insnp)
459 (!unaligned_ok && offset >= 0 && 459 (!unaligned_ok && offset >= 0 &&
460 offset + ip_align >= 0 && 460 offset + ip_align >= 0 &&
461 offset + ip_align % size == 0))) { 461 offset + ip_align % size == 0))) {
462 bool ldx_off_ok = offset <= S16_MAX;
463
462 *insn++ = BPF_MOV64_REG(BPF_REG_TMP, BPF_REG_H); 464 *insn++ = BPF_MOV64_REG(BPF_REG_TMP, BPF_REG_H);
463 *insn++ = BPF_ALU64_IMM(BPF_SUB, BPF_REG_TMP, offset); 465 *insn++ = BPF_ALU64_IMM(BPF_SUB, BPF_REG_TMP, offset);
464 *insn++ = BPF_JMP_IMM(BPF_JSLT, BPF_REG_TMP, size, 2 + endian); 466 *insn++ = BPF_JMP_IMM(BPF_JSLT, BPF_REG_TMP,
465 *insn++ = BPF_LDX_MEM(BPF_SIZE(fp->code), BPF_REG_A, BPF_REG_D, 467 size, 2 + endian + (!ldx_off_ok * 2));
466 offset); 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 }
467 if (endian) 477 if (endian)
468 *insn++ = BPF_ENDIAN(BPF_FROM_BE, BPF_REG_A, size * 8); 478 *insn++ = BPF_ENDIAN(BPF_FROM_BE, BPF_REG_A, size * 8);
469 *insn++ = BPF_JMP_A(8); 479 *insn++ = BPF_JMP_A(8);
@@ -4526,10 +4536,10 @@ static const struct bpf_func_proto bpf_lwt_push_encap_proto = {
4526 .arg4_type = ARG_CONST_SIZE 4536 .arg4_type = ARG_CONST_SIZE
4527}; 4537};
4528 4538
4539#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
4529BPF_CALL_4(bpf_lwt_seg6_store_bytes, struct sk_buff *, skb, u32, offset, 4540BPF_CALL_4(bpf_lwt_seg6_store_bytes, struct sk_buff *, skb, u32, offset,
4530 const void *, from, u32, len) 4541 const void *, from, u32, len)
4531{ 4542{
4532#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
4533 struct seg6_bpf_srh_state *srh_state = 4543 struct seg6_bpf_srh_state *srh_state =
4534 this_cpu_ptr(&seg6_bpf_srh_states); 4544 this_cpu_ptr(&seg6_bpf_srh_states);
4535 void *srh_tlvs, *srh_end, *ptr; 4545 void *srh_tlvs, *srh_end, *ptr;
@@ -4555,9 +4565,6 @@ BPF_CALL_4(bpf_lwt_seg6_store_bytes, struct sk_buff *, skb, u32, offset,
4555 4565
4556 memcpy(skb->data + offset, from, len); 4566 memcpy(skb->data + offset, from, len);
4557 return 0; 4567 return 0;
4558#else /* CONFIG_IPV6_SEG6_BPF */
4559 return -EOPNOTSUPP;
4560#endif
4561} 4568}
4562 4569
4563static const struct bpf_func_proto bpf_lwt_seg6_store_bytes_proto = { 4570static 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 = {
4573BPF_CALL_4(bpf_lwt_seg6_action, struct sk_buff *, skb, 4580BPF_CALL_4(bpf_lwt_seg6_action, struct sk_buff *, skb,
4574 u32, action, void *, param, u32, param_len) 4581 u32, action, void *, param, u32, param_len)
4575{ 4582{
4576#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
4577 struct seg6_bpf_srh_state *srh_state = 4583 struct seg6_bpf_srh_state *srh_state =
4578 this_cpu_ptr(&seg6_bpf_srh_states); 4584 this_cpu_ptr(&seg6_bpf_srh_states);
4579 struct ipv6_sr_hdr *srh; 4585 struct ipv6_sr_hdr *srh;
@@ -4621,9 +4627,6 @@ BPF_CALL_4(bpf_lwt_seg6_action, struct sk_buff *, skb,
4621 default: 4627 default:
4622 return -EINVAL; 4628 return -EINVAL;
4623 } 4629 }
4624#else /* CONFIG_IPV6_SEG6_BPF */
4625 return -EOPNOTSUPP;
4626#endif
4627} 4630}
4628 4631
4629static const struct bpf_func_proto bpf_lwt_seg6_action_proto = { 4632static 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 = {
4639BPF_CALL_3(bpf_lwt_seg6_adjust_srh, struct sk_buff *, skb, u32, offset, 4642BPF_CALL_3(bpf_lwt_seg6_adjust_srh, struct sk_buff *, skb, u32, offset,
4640 s32, len) 4643 s32, len)
4641{ 4644{
4642#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
4643 struct seg6_bpf_srh_state *srh_state = 4645 struct seg6_bpf_srh_state *srh_state =
4644 this_cpu_ptr(&seg6_bpf_srh_states); 4646 this_cpu_ptr(&seg6_bpf_srh_states);
4645 void *srh_end, *srh_tlvs, *ptr; 4647 void *srh_end, *srh_tlvs, *ptr;
@@ -4683,9 +4685,6 @@ BPF_CALL_3(bpf_lwt_seg6_adjust_srh, struct sk_buff *, skb, u32, offset,
4683 srh_state->hdrlen += len; 4685 srh_state->hdrlen += len;
4684 srh_state->valid = 0; 4686 srh_state->valid = 0;
4685 return 0; 4687 return 0;
4686#else /* CONFIG_IPV6_SEG6_BPF */
4687 return -EOPNOTSUPP;
4688#endif
4689} 4688}
4690 4689
4691static const struct bpf_func_proto bpf_lwt_seg6_adjust_srh_proto = { 4690static 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 = {
4696 .arg2_type = ARG_ANYTHING, 4695 .arg2_type = ARG_ANYTHING,
4697 .arg3_type = ARG_ANYTHING, 4696 .arg3_type = ARG_ANYTHING,
4698}; 4697};
4698#endif /* CONFIG_IPV6_SEG6_BPF */
4699 4699
4700bool bpf_helper_changes_pkt_data(void *func) 4700bool bpf_helper_changes_pkt_data(void *func)
4701{ 4701{
@@ -4717,11 +4717,12 @@ bool bpf_helper_changes_pkt_data(void *func)
4717 func == bpf_xdp_adjust_meta || 4717 func == bpf_xdp_adjust_meta ||
4718 func == bpf_msg_pull_data || 4718 func == bpf_msg_pull_data ||
4719 func == bpf_xdp_adjust_tail || 4719 func == bpf_xdp_adjust_tail ||
4720 func == bpf_lwt_push_encap || 4720#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
4721 func == bpf_lwt_seg6_store_bytes || 4721 func == bpf_lwt_seg6_store_bytes ||
4722 func == bpf_lwt_seg6_adjust_srh || 4722 func == bpf_lwt_seg6_adjust_srh ||
4723 func == bpf_lwt_seg6_action 4723 func == bpf_lwt_seg6_action ||
4724 ) 4724#endif
4725 func == bpf_lwt_push_encap)
4725 return true; 4726 return true;
4726 4727
4727 return false; 4728 return false;
@@ -5056,12 +5057,14 @@ static const struct bpf_func_proto *
5056lwt_seg6local_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 5057lwt_seg6local_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
5057{ 5058{
5058 switch (func_id) { 5059 switch (func_id) {
5060#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
5059 case BPF_FUNC_lwt_seg6_store_bytes: 5061 case BPF_FUNC_lwt_seg6_store_bytes:
5060 return &bpf_lwt_seg6_store_bytes_proto; 5062 return &bpf_lwt_seg6_store_bytes_proto;
5061 case BPF_FUNC_lwt_seg6_action: 5063 case BPF_FUNC_lwt_seg6_action:
5062 return &bpf_lwt_seg6_action_proto; 5064 return &bpf_lwt_seg6_action_proto;
5063 case BPF_FUNC_lwt_seg6_adjust_srh: 5065 case BPF_FUNC_lwt_seg6_adjust_srh:
5064 return &bpf_lwt_seg6_adjust_srh_proto; 5066 return &bpf_lwt_seg6_adjust_srh_proto;
5067#endif
5065 default: 5068 default:
5066 return lwt_out_func_proto(func_id, prog); 5069 return lwt_out_func_proto(func_id, prog);
5067 } 5070 }
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 7d220cbd09b6..72335c2e8108 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -218,9 +218,6 @@ static int xsk_generic_xmit(struct sock *sk, struct msghdr *m,
218 struct sk_buff *skb; 218 struct sk_buff *skb;
219 int err = 0; 219 int err = 0;
220 220
221 if (unlikely(!xs->tx))
222 return -ENOBUFS;
223
224 mutex_lock(&xs->mutex); 221 mutex_lock(&xs->mutex);
225 222
226 while (xskq_peek_desc(xs->tx, &desc)) { 223 while (xskq_peek_desc(xs->tx, &desc)) {
@@ -233,22 +230,13 @@ static int xsk_generic_xmit(struct sock *sk, struct msghdr *m,
233 goto out; 230 goto out;
234 } 231 }
235 232
236 if (xskq_reserve_addr(xs->umem->cq)) { 233 if (xskq_reserve_addr(xs->umem->cq))
237 err = -EAGAIN;
238 goto out; 234 goto out;
239 }
240 235
241 len = desc.len; 236 if (xs->queue_id >= xs->dev->real_num_tx_queues)
242 if (unlikely(len > xs->dev->mtu)) {
243 err = -EMSGSIZE;
244 goto out; 237 goto out;
245 }
246
247 if (xs->queue_id >= xs->dev->real_num_tx_queues) {
248 err = -ENXIO;
249 goto out;
250 }
251 238
239 len = desc.len;
252 skb = sock_alloc_send_skb(sk, len, 1, &err); 240 skb = sock_alloc_send_skb(sk, len, 1, &err);
253 if (unlikely(!skb)) { 241 if (unlikely(!skb)) {
254 err = -EAGAIN; 242 err = -EAGAIN;
@@ -300,6 +288,8 @@ static int xsk_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len)
300 return -ENXIO; 288 return -ENXIO;
301 if (unlikely(!(xs->dev->flags & IFF_UP))) 289 if (unlikely(!(xs->dev->flags & IFF_UP)))
302 return -ENETDOWN; 290 return -ENETDOWN;
291 if (unlikely(!xs->tx))
292 return -ENOBUFS;
303 if (need_wait) 293 if (need_wait)
304 return -EOPNOTSUPP; 294 return -EOPNOTSUPP;
305 295
diff --git a/samples/bpf/xdp2skb_meta.sh b/samples/bpf/xdp2skb_meta.sh
index b9c9549c4c27..4bde9d066c46 100755
--- a/samples/bpf/xdp2skb_meta.sh
+++ b/samples/bpf/xdp2skb_meta.sh
@@ -16,8 +16,8 @@
16BPF_FILE=xdp2skb_meta_kern.o 16BPF_FILE=xdp2skb_meta_kern.o
17DIR=$(dirname $0) 17DIR=$(dirname $0)
18 18
19export TC=/usr/sbin/tc 19[ -z "$TC" ] && TC=tc
20export IP=/usr/sbin/ip 20[ -z "$IP" ] && IP=ip
21 21
22function usage() { 22function usage() {
23 echo "" 23 echo ""
@@ -53,7 +53,7 @@ function _call_cmd() {
53 local allow_fail="$2" 53 local allow_fail="$2"
54 shift 2 54 shift 2
55 if [[ -n "$VERBOSE" ]]; then 55 if [[ -n "$VERBOSE" ]]; then
56 echo "$(basename $cmd) $@" 56 echo "$cmd $@"
57 fi 57 fi
58 if [[ -n "$DRYRUN" ]]; then 58 if [[ -n "$DRYRUN" ]]; then
59 return 59 return
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 2ecd27b670d7..f5f7bcc96046 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -4975,6 +4975,24 @@ static struct bpf_test tests[] = {
4975 .prog_type = BPF_PROG_TYPE_LWT_XMIT, 4975 .prog_type = BPF_PROG_TYPE_LWT_XMIT,
4976 }, 4976 },
4977 { 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 },
4995 {
4978 "invalid access of tc_classid for LWT_IN", 4996 "invalid access of tc_classid for LWT_IN",
4979 .insns = { 4997 .insns = {
4980 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 4998 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
@@ -12554,8 +12572,11 @@ static void do_test_single(struct bpf_test *test, bool unpriv,
12554 } 12572 }
12555 12573
12556 if (fd_prog >= 0) { 12574 if (fd_prog >= 0) {
12575 __u8 tmp[TEST_DATA_LEN << 2];
12576 __u32 size_tmp = sizeof(tmp);
12577
12557 err = bpf_prog_test_run(fd_prog, 1, test->data, 12578 err = bpf_prog_test_run(fd_prog, 1, test->data,
12558 sizeof(test->data), NULL, NULL, 12579 sizeof(test->data), tmp, &size_tmp,
12559 &retval, NULL); 12580 &retval, NULL);
12560 if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) { 12581 if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
12561 printf("Unexpected bpf_prog_test_run error\n"); 12582 printf("Unexpected bpf_prog_test_run error\n");