Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6436408e authored by David S. Miller's avatar David S. Miller
Browse files


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: default avatarDavid S. Miller <davem@davemloft.net>
parents df133f3f e7c87bd6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -467,7 +467,7 @@ static const struct btf_kind_operations *btf_type_ops(const struct btf_type *t)
	return kind_ops[BTF_INFO_KIND(t->info)];
}

bool btf_name_offset_valid(const struct btf *btf, u32 offset)
static bool btf_name_offset_valid(const struct btf *btf, u32 offset)
{
	return BTF_STR_OFFSET_VALID(offset) &&
		offset < btf->hdr.str_len;
+1 −0
Original line number Diff line number Diff line
@@ -718,6 +718,7 @@ cgroup_dev_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
	case BPF_FUNC_trace_printk:
		if (capable(CAP_SYS_ADMIN))
			return bpf_get_trace_printk_proto();
		/* fall through */
	default:
		return NULL;
	}
+15 −2
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd)
{
	struct bpf_map *inner_map, *inner_map_meta;
	u32 inner_map_meta_size;
	struct fd f;

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

	inner_map_meta = kzalloc(sizeof(*inner_map_meta), GFP_USER);
	inner_map_meta_size = sizeof(*inner_map_meta);
	/* In some cases verifier needs to access beyond just base map. */
	if (inner_map->ops == &array_map_ops)
		inner_map_meta_size = sizeof(struct bpf_array);

	inner_map_meta = kzalloc(inner_map_meta_size, GFP_USER);
	if (!inner_map_meta) {
		fdput(f);
		return ERR_PTR(-ENOMEM);
@@ -46,9 +52,16 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd)
	inner_map_meta->key_size = inner_map->key_size;
	inner_map_meta->value_size = inner_map->value_size;
	inner_map_meta->map_flags = inner_map->map_flags;
	inner_map_meta->ops = inner_map->ops;
	inner_map_meta->max_entries = inner_map->max_entries;

	/* Misc members not needed in bpf_map_meta_equal() check. */
	inner_map_meta->ops = inner_map->ops;
	if (inner_map->ops == &array_map_ops) {
		inner_map_meta->unpriv_array = inner_map->unpriv_array;
		container_of(inner_map_meta, struct bpf_array, map)->index_mask =
		     container_of(inner_map, struct bpf_array, map)->index_mask;
	}

	fdput(f);
	return inner_map_meta;
}
+7 −2
Original line number Diff line number Diff line
@@ -180,11 +180,14 @@ static inline int stack_map_parse_build_id(void *page_addr,

		if (nhdr->n_type == BPF_BUILD_ID &&
		    nhdr->n_namesz == sizeof("GNU") &&
		    nhdr->n_descsz == BPF_BUILD_ID_SIZE) {
		    nhdr->n_descsz > 0 &&
		    nhdr->n_descsz <= BPF_BUILD_ID_SIZE) {
			memcpy(build_id,
			       note_start + note_offs +
			       ALIGN(sizeof("GNU"), 4) + sizeof(Elf32_Nhdr),
			       BPF_BUILD_ID_SIZE);
			       nhdr->n_descsz);
			memset(build_id + nhdr->n_descsz, 0,
			       BPF_BUILD_ID_SIZE - nhdr->n_descsz);
			return 0;
		}
		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,
		for (i = 0; i < trace_nr; i++) {
			id_offs[i].status = BPF_STACK_BUILD_ID_IP;
			id_offs[i].ip = ips[i];
			memset(id_offs[i].build_id, 0, BPF_BUILD_ID_SIZE);
		}
		return;
	}
@@ -321,6 +325,7 @@ static void stack_map_get_build_id_offset(struct bpf_stack_build_id *id_offs,
			/* per entry fall back to ips */
			id_offs[i].status = BPF_STACK_BUILD_ID_IP;
			id_offs[i].ip = ips[i];
			memset(id_offs[i].build_id, 0, BPF_BUILD_ID_SIZE);
			continue;
		}
		id_offs[i].offset = (vma->vm_pgoff << PAGE_SHIFT) + ips[i]
+20 −12
Original line number Diff line number Diff line
@@ -2020,9 +2020,9 @@ static inline int __bpf_tx_skb(struct net_device *dev, struct sk_buff *skb)
static int __bpf_redirect_no_mac(struct sk_buff *skb, struct net_device *dev,
				 u32 flags)
{
	/* skb->mac_len is not set on normal egress */
	unsigned int mlen = skb->network_header - skb->mac_header;
	unsigned int mlen = skb_network_offset(skb);

	if (mlen) {
		__skb_pull(skb, mlen);

		/* At ingress, the mac header has already been pulled once.
@@ -2032,6 +2032,7 @@ static int __bpf_redirect_no_mac(struct sk_buff *skb, struct net_device *dev,
		 */
		if (!skb_at_tc_ingress(skb))
			skb_postpull_rcsum(skb, skb_mac_header(skb), mlen);
	}
	skb_pop_mac_header(skb);
	skb_reset_mac_len(skb);
	return flags & BPF_F_INGRESS ?
@@ -4119,6 +4120,10 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock,
			sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF);
			break;
		case SO_MAX_PACING_RATE: /* 32bit version */
			if (val != ~0U)
				cmpxchg(&sk->sk_pacing_status,
					SK_PACING_NONE,
					SK_PACING_NEEDED);
			sk->sk_max_pacing_rate = (val == ~0U) ? ~0UL : val;
			sk->sk_pacing_rate = min(sk->sk_pacing_rate,
						 sk->sk_max_pacing_rate);
@@ -4132,7 +4137,10 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock,
			sk->sk_rcvlowat = val ? : 1;
			break;
		case SO_MARK:
			if (sk->sk_mark != val) {
				sk->sk_mark = val;
				sk_dst_reset(sk);
			}
			break;
		default:
			ret = -EINVAL;
@@ -5309,7 +5317,7 @@ bpf_base_func_proto(enum bpf_func_id func_id)
	case BPF_FUNC_trace_printk:
		if (capable(CAP_SYS_ADMIN))
			return bpf_get_trace_printk_proto();
		/* else: fall through */
		/* else, fall through */
	default:
		return NULL;
	}
Loading