Skip to content

Commit

Permalink
bpf: Don't EFAULT for getsockopt with optval=NULL
Browse files Browse the repository at this point in the history
Some socket options do getsockopt with optval=NULL to estimate the size
of the final buffer (which is returned via optlen). This breaks BPF
getsockopt assumptions about permitted optval buffer size. Let's enforce
these assumptions only when non-NULL optval is provided.

Fixes: 0d01da6 ("bpf: implement getsockopt and setsockopt hooks")
Reported-by: Martin KaFai Lau <martin.lau@kernel.org>
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/ZD7Js4fj5YyI2oLd@google.com/T/#mb68daf700f87a9244a15d01d00c3f0e5b08f49f7
Link: https://lore.kernel.org/bpf/20230418225343.553806-2-sdf@google.com
  • Loading branch information
Stanislav Fomichev authored and Daniel Borkmann committed Apr 21, 2023
1 parent 02e93e0 commit 00e74ae
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions kernel/bpf/cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1921,14 +1921,17 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
if (ret < 0)
goto out;

if (ctx.optlen > max_optlen || ctx.optlen < 0) {
if (optval && (ctx.optlen > max_optlen || ctx.optlen < 0)) {
ret = -EFAULT;
goto out;
}

if (ctx.optlen != 0) {
if (copy_to_user(optval, ctx.optval, ctx.optlen) ||
put_user(ctx.optlen, optlen)) {
if (optval && copy_to_user(optval, ctx.optval, ctx.optlen)) {
ret = -EFAULT;
goto out;
}
if (put_user(ctx.optlen, optlen)) {
ret = -EFAULT;
goto out;
}
Expand Down

0 comments on commit 00e74ae

Please sign in to comment.