Skip to content

Commit 752ba56

Browse files
l0koddavem330
authored andcommitted
bpf: Extend check_uarg_tail_zero() checks
The function check_uarg_tail_zero() was created from bpf(2) for BPF_OBJ_GET_INFO_BY_FD without taking the access_ok() nor the PAGE_SIZE checks. Make this checks more generally available while unlikely to be triggered, extend the memory range check and add an explanation including why the ToCToU should not be a security concern. Signed-off-by: Mickaël Salaün <[email protected]> Acked-by: Daniel Borkmann <[email protected]> Cc: Alexei Starovoitov <[email protected]> Cc: David S. Miller <[email protected]> Cc: Kees Cook <[email protected]> Cc: Martin KaFai Lau <[email protected]> Link: https://lkml.kernel.org/r/CAGXu5j+vRGFvJZmjtAcT8Hi8B+Wz0e1b6VKYZHfQP_=DXzC4CQ@mail.gmail.com Signed-off-by: David S. Miller <[email protected]>
1 parent 58291a7 commit 752ba56

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

kernel/bpf/syscall.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ static const struct bpf_map_ops * const bpf_map_types[] = {
4848
#undef BPF_MAP_TYPE
4949
};
5050

51+
/*
52+
* If we're handed a bigger struct than we know of, ensure all the unknown bits
53+
* are 0 - i.e. new user-space does not rely on any kernel feature extensions
54+
* we don't know about yet.
55+
*
56+
* There is a ToCToU between this function call and the following
57+
* copy_from_user() call. However, this is not a concern since this function is
58+
* meant to be a future-proofing of bits.
59+
*/
5160
static int check_uarg_tail_zero(void __user *uaddr,
5261
size_t expected_size,
5362
size_t actual_size)
@@ -57,6 +66,12 @@ static int check_uarg_tail_zero(void __user *uaddr,
5766
unsigned char val;
5867
int err;
5968

69+
if (unlikely(actual_size > PAGE_SIZE)) /* silly large */
70+
return -E2BIG;
71+
72+
if (unlikely(!access_ok(VERIFY_READ, uaddr, actual_size)))
73+
return -EFAULT;
74+
6075
if (actual_size <= expected_size)
6176
return 0;
6277

@@ -1393,17 +1408,6 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
13931408
if (!capable(CAP_SYS_ADMIN) && sysctl_unprivileged_bpf_disabled)
13941409
return -EPERM;
13951410

1396-
if (!access_ok(VERIFY_READ, uattr, 1))
1397-
return -EFAULT;
1398-
1399-
if (size > PAGE_SIZE) /* silly large */
1400-
return -E2BIG;
1401-
1402-
/* If we're handed a bigger struct than we know of,
1403-
* ensure all the unknown bits are 0 - i.e. new
1404-
* user-space does not rely on any kernel feature
1405-
* extensions we dont know about yet.
1406-
*/
14071411
err = check_uarg_tail_zero(uattr, sizeof(attr), size);
14081412
if (err)
14091413
return err;

0 commit comments

Comments
 (0)