Skip to content

Commit c9d99cf

Browse files
committed
Daniel Borkmann says: ==================== pull-request: bpf 2023-06-07 We've added 7 non-merge commits during the last 7 day(s) which contain a total of 12 files changed, 112 insertions(+), 7 deletions(-). The main changes are: 1) Fix a use-after-free in BPF's task local storage, from KP Singh. 2) Make struct path handling more robust in bpf_d_path, from Jiri Olsa. 3) Fix a syzbot NULL-pointer dereference in sockmap, from Eric Dumazet. 4) UAPI fix for BPF_NETFILTER before final kernel ships, from Florian Westphal. 5) Fix map-in-map array_map_gen_lookup code generation where elem_size was not being set for inner maps, from Rhys Rustad-Elliott. 6) Fix sockopt_sk selftest's NETLINK_LIST_MEMBERSHIPS assertion, from Yonghong Song. * tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: bpf: Add extra path pointer check to d_path helper selftests/bpf: Fix sockopt_sk selftest bpf: netfilter: Add BPF_NETFILTER bpf_attach_type selftests/bpf: Add access_inner_map selftest bpf: Fix elem_size not being set for inner maps bpf: Fix UAF in task local storage bpf, sockmap: Avoid potential NULL dereference in sk_psock_verdict_data_ready() ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 7c5d480 + f46fab0 commit c9d99cf

File tree

12 files changed

+112
-7
lines changed

12 files changed

+112
-7
lines changed

include/uapi/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,7 @@ enum bpf_attach_type {
10351035
BPF_TRACE_KPROBE_MULTI,
10361036
BPF_LSM_CGROUP,
10371037
BPF_STRUCT_OPS,
1038+
BPF_NETFILTER,
10381039
__MAX_BPF_ATTACH_TYPE
10391040
};
10401041

kernel/bpf/map_in_map.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,13 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd)
6969
/* Misc members not needed in bpf_map_meta_equal() check. */
7070
inner_map_meta->ops = inner_map->ops;
7171
if (inner_map->ops == &array_map_ops) {
72+
struct bpf_array *inner_array_meta =
73+
container_of(inner_map_meta, struct bpf_array, map);
74+
struct bpf_array *inner_array = container_of(inner_map, struct bpf_array, map);
75+
76+
inner_array_meta->index_mask = inner_array->index_mask;
77+
inner_array_meta->elem_size = inner_array->elem_size;
7278
inner_map_meta->bypass_spec_v1 = inner_map->bypass_spec_v1;
73-
container_of(inner_map_meta, struct bpf_array, map)->index_mask =
74-
container_of(inner_map, struct bpf_array, map)->index_mask;
7579
}
7680

7781
fdput(f);

kernel/bpf/syscall.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2433,6 +2433,10 @@ bpf_prog_load_check_attach(enum bpf_prog_type prog_type,
24332433
default:
24342434
return -EINVAL;
24352435
}
2436+
case BPF_PROG_TYPE_NETFILTER:
2437+
if (expected_attach_type == BPF_NETFILTER)
2438+
return 0;
2439+
return -EINVAL;
24362440
case BPF_PROG_TYPE_SYSCALL:
24372441
case BPF_PROG_TYPE_EXT:
24382442
if (expected_attach_type)
@@ -4590,7 +4594,12 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
45904594

45914595
switch (prog->type) {
45924596
case BPF_PROG_TYPE_EXT:
4597+
break;
45934598
case BPF_PROG_TYPE_NETFILTER:
4599+
if (attr->link_create.attach_type != BPF_NETFILTER) {
4600+
ret = -EINVAL;
4601+
goto out;
4602+
}
45944603
break;
45954604
case BPF_PROG_TYPE_PERF_EVENT:
45964605
case BPF_PROG_TYPE_TRACEPOINT:

kernel/fork.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ void free_task(struct task_struct *tsk)
627627
arch_release_task_struct(tsk);
628628
if (tsk->flags & PF_KTHREAD)
629629
free_kthread_struct(tsk);
630+
bpf_task_storage_free(tsk);
630631
free_task_struct(tsk);
631632
}
632633
EXPORT_SYMBOL(free_task);
@@ -979,7 +980,6 @@ void __put_task_struct(struct task_struct *tsk)
979980
cgroup_free(tsk);
980981
task_numa_free(tsk, true);
981982
security_task_free(tsk);
982-
bpf_task_storage_free(tsk);
983983
exit_creds(tsk);
984984
delayacct_tsk_free(tsk);
985985
put_signal_struct(tsk->signal);

kernel/trace/bpf_trace.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -900,13 +900,23 @@ static const struct bpf_func_proto bpf_send_signal_thread_proto = {
900900

901901
BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz)
902902
{
903+
struct path copy;
903904
long len;
904905
char *p;
905906

906907
if (!sz)
907908
return 0;
908909

909-
p = d_path(path, buf, sz);
910+
/*
911+
* The path pointer is verified as trusted and safe to use,
912+
* but let's double check it's valid anyway to workaround
913+
* potentially broken verifier.
914+
*/
915+
len = copy_from_kernel_nofault(&copy, path, sizeof(*path));
916+
if (len < 0)
917+
return len;
918+
919+
p = d_path(&copy, buf, sz);
910920
if (IS_ERR(p)) {
911921
len = PTR_ERR(p);
912922
} else {

net/core/skmsg.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,8 @@ static void sk_psock_verdict_data_ready(struct sock *sk)
12101210

12111211
rcu_read_lock();
12121212
psock = sk_psock(sk);
1213-
psock->saved_data_ready(sk);
1213+
if (psock)
1214+
psock->saved_data_ready(sk);
12141215
rcu_read_unlock();
12151216
}
12161217
}

tools/include/uapi/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,7 @@ enum bpf_attach_type {
10351035
BPF_TRACE_KPROBE_MULTI,
10361036
BPF_LSM_CGROUP,
10371037
BPF_STRUCT_OPS,
1038+
BPF_NETFILTER,
10381039
__MAX_BPF_ATTACH_TYPE
10391040
};
10401041

tools/lib/bpf/libbpf.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ static const char * const attach_type_name[] = {
117117
[BPF_PERF_EVENT] = "perf_event",
118118
[BPF_TRACE_KPROBE_MULTI] = "trace_kprobe_multi",
119119
[BPF_STRUCT_OPS] = "struct_ops",
120+
[BPF_NETFILTER] = "netfilter",
120121
};
121122

122123
static const char * const link_type_name[] = {
@@ -8712,7 +8713,7 @@ static const struct bpf_sec_def section_defs[] = {
87128713
SEC_DEF("struct_ops+", STRUCT_OPS, 0, SEC_NONE),
87138714
SEC_DEF("struct_ops.s+", STRUCT_OPS, 0, SEC_SLEEPABLE),
87148715
SEC_DEF("sk_lookup", SK_LOOKUP, BPF_SK_LOOKUP, SEC_ATTACHABLE),
8715-
SEC_DEF("netfilter", NETFILTER, 0, SEC_NONE),
8716+
SEC_DEF("netfilter", NETFILTER, BPF_NETFILTER, SEC_NONE),
87168717
};
87178718

87188719
static size_t custom_sec_def_cnt;

tools/lib/bpf/libbpf_probes.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,9 @@ static int probe_prog_load(enum bpf_prog_type prog_type,
180180
case BPF_PROG_TYPE_SK_REUSEPORT:
181181
case BPF_PROG_TYPE_FLOW_DISSECTOR:
182182
case BPF_PROG_TYPE_CGROUP_SYSCTL:
183+
break;
183184
case BPF_PROG_TYPE_NETFILTER:
185+
opts.expected_attach_type = BPF_NETFILTER;
184186
break;
185187
default:
186188
return -EOPNOTSUPP;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
3+
#include <test_progs.h>
4+
5+
#include "inner_array_lookup.skel.h"
6+
7+
void test_inner_array_lookup(void)
8+
{
9+
int map1_fd, err;
10+
int key = 3;
11+
int val = 1;
12+
struct inner_array_lookup *skel;
13+
14+
skel = inner_array_lookup__open_and_load();
15+
if (!ASSERT_OK_PTR(skel, "open_load_skeleton"))
16+
return;
17+
18+
err = inner_array_lookup__attach(skel);
19+
if (!ASSERT_OK(err, "skeleton_attach"))
20+
goto cleanup;
21+
22+
map1_fd = bpf_map__fd(skel->maps.inner_map1);
23+
bpf_map_update_elem(map1_fd, &key, &val, 0);
24+
25+
/* Probe should have set the element at index 3 to 2 */
26+
bpf_map_lookup_elem(map1_fd, &key, &val);
27+
ASSERT_EQ(val, 2, "value_is_2");
28+
29+
cleanup:
30+
inner_array_lookup__destroy(skel);
31+
}

0 commit comments

Comments
 (0)