hid_bpf_get_data() returns a pointer into the HID-BPF context data when
the caller-provided offset and size fit inside ctx->allocated_size.

The current check adds rdwr_buf_size and offset before comparing the
result against ctx->allocated_size. Since both values are unsigned, a
very large size can wrap the sum below ctx->allocated_size and make the
helper return a pointer even though the requested range is not contained
in the backing buffer.

Use check_add_overflow() to reject wrapped range ends before comparing
the requested range end against ctx->allocated_size.

Fixes: 658ee5a64fcf ("HID: bpf: allocate data memory for device_event BPF 
programs")
Signed-off-by: Yiyang Chen <[email protected]>
---
 drivers/hid/bpf/hid_bpf_dispatch.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c 
b/drivers/hid/bpf/hid_bpf_dispatch.c
index d0130658091b0..536f6d01fd14c 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -17,6 +17,7 @@
 #include <linux/kfifo.h>
 #include <linux/minmax.h>
 #include <linux/module.h>
+#include <linux/overflow.h>
 #include "hid_bpf_dispatch.h"
 
 const struct hid_ops *hid_ops;
@@ -296,10 +297,12 @@ __bpf_kfunc __u8 *
 hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t 
rdwr_buf_size)
 {
        struct hid_bpf_ctx_kern *ctx_kern;
+       size_t end;
 
        ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
 
-       if (rdwr_buf_size + offset > ctx->allocated_size)
+       if (check_add_overflow(rdwr_buf_size, offset, &end) ||
+           end > ctx->allocated_size)
                return NULL;
 
        return ctx_kern->data + offset;
-- 
2.34.1


Reply via email to