Make sure that user requested memory via BLKTRACESETUP is within bounds. This can be easily exploited by setting really large values for buf_size and buf_nr in BLKTRACESETUP ioctl. blktrace program has following hardcoded values for bufsize and bufnr: BUF_SIZE=(512 * 1024) BUF_NR=(4) We add buffer to this and define the upper bound to be as follows: BUF_SIZE=(1024 * 1024) BUF_NR=(16) This is very easy to exploit. Setting buf_size / buf_nr in userspace program to big values make kernel go oom. Verified that the fix makes BLKTRACESETUP return -E2BIG if the buf_size * buf_nr crosses the upper bound. Signed-off-by: Harshad Shirwadkar <harshadshirwadkar@xxxxxxxxx> --- include/uapi/linux/blktrace_api.h | 3 +++ kernel/trace/blktrace.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/include/uapi/linux/blktrace_api.h b/include/uapi/linux/blktrace_api.h index 690621b610e5..4d9dc44a83f9 100644 --- a/include/uapi/linux/blktrace_api.h +++ b/include/uapi/linux/blktrace_api.h @@ -129,6 +129,9 @@ enum { }; #define BLKTRACE_BDEV_SIZE 32 +#define BLKTRACE_MAX_BUFSIZ (1024 * 1024) +#define BLKTRACE_MAX_BUFNR 16 +#define BLKTRACE_MAX_ALLOC ((BLKTRACE_MAX_BUFNR) * (BLKTRACE_MAX_BUFNR)) /* * User setup structure passed with BLKTRACESETUP diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index ea47f2084087..b3b0a8164c05 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -482,6 +482,9 @@ static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, if (!buts->buf_size || !buts->buf_nr) return -EINVAL; + if (buts->buf_size * buts->buf_nr > BLKTRACE_MAX_ALLOC) + return -E2BIG; + if (!blk_debugfs_root) return -ENOENT; -- 2.27.0.rc2.251.g90737beb825-goog