Merge tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
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/20230607220514.29698-1-daniel@iogearbox.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -69,9 +69,13 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd)
|
||||
/* Misc members not needed in bpf_map_meta_equal() check. */
|
||||
inner_map_meta->ops = inner_map->ops;
|
||||
if (inner_map->ops == &array_map_ops) {
|
||||
struct bpf_array *inner_array_meta =
|
||||
container_of(inner_map_meta, struct bpf_array, map);
|
||||
struct bpf_array *inner_array = container_of(inner_map, struct bpf_array, map);
|
||||
|
||||
inner_array_meta->index_mask = inner_array->index_mask;
|
||||
inner_array_meta->elem_size = inner_array->elem_size;
|
||||
inner_map_meta->bypass_spec_v1 = inner_map->bypass_spec_v1;
|
||||
container_of(inner_map_meta, struct bpf_array, map)->index_mask =
|
||||
container_of(inner_map, struct bpf_array, map)->index_mask;
|
||||
}
|
||||
|
||||
fdput(f);
|
||||
|
@@ -2433,6 +2433,10 @@ bpf_prog_load_check_attach(enum bpf_prog_type prog_type,
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
case BPF_PROG_TYPE_NETFILTER:
|
||||
if (expected_attach_type == BPF_NETFILTER)
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
case BPF_PROG_TYPE_SYSCALL:
|
||||
case BPF_PROG_TYPE_EXT:
|
||||
if (expected_attach_type)
|
||||
@@ -4590,7 +4594,12 @@ static int link_create(union bpf_attr *attr, bpfptr_t uattr)
|
||||
|
||||
switch (prog->type) {
|
||||
case BPF_PROG_TYPE_EXT:
|
||||
break;
|
||||
case BPF_PROG_TYPE_NETFILTER:
|
||||
if (attr->link_create.attach_type != BPF_NETFILTER) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case BPF_PROG_TYPE_PERF_EVENT:
|
||||
case BPF_PROG_TYPE_TRACEPOINT:
|
||||
|
@@ -627,6 +627,7 @@ void free_task(struct task_struct *tsk)
|
||||
arch_release_task_struct(tsk);
|
||||
if (tsk->flags & PF_KTHREAD)
|
||||
free_kthread_struct(tsk);
|
||||
bpf_task_storage_free(tsk);
|
||||
free_task_struct(tsk);
|
||||
}
|
||||
EXPORT_SYMBOL(free_task);
|
||||
@@ -979,7 +980,6 @@ void __put_task_struct(struct task_struct *tsk)
|
||||
cgroup_free(tsk);
|
||||
task_numa_free(tsk, true);
|
||||
security_task_free(tsk);
|
||||
bpf_task_storage_free(tsk);
|
||||
exit_creds(tsk);
|
||||
delayacct_tsk_free(tsk);
|
||||
put_signal_struct(tsk->signal);
|
||||
|
@@ -900,13 +900,23 @@ static const struct bpf_func_proto bpf_send_signal_thread_proto = {
|
||||
|
||||
BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz)
|
||||
{
|
||||
struct path copy;
|
||||
long len;
|
||||
char *p;
|
||||
|
||||
if (!sz)
|
||||
return 0;
|
||||
|
||||
p = d_path(path, buf, sz);
|
||||
/*
|
||||
* The path pointer is verified as trusted and safe to use,
|
||||
* but let's double check it's valid anyway to workaround
|
||||
* potentially broken verifier.
|
||||
*/
|
||||
len = copy_from_kernel_nofault(©, path, sizeof(*path));
|
||||
if (len < 0)
|
||||
return len;
|
||||
|
||||
p = d_path(©, buf, sz);
|
||||
if (IS_ERR(p)) {
|
||||
len = PTR_ERR(p);
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user