Re: [PATCH] blktrace: put bounds on BLKTRACESETUP buf_size and buf_nr

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 6/3/20 10:45 PM, Harshad Shirwadkar wrote:
> 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)
> 
Aren't these values should be system dependent to start with?
I wonder what are the side effects of having hard-coded values ?
> 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))
>   
This is an API change and should be reflected to kernel & userspace 
tools. One way of doing it is to remove BUF_SIZE and BUF_NR and sync
kernel header with userspace blktrace_api.h.

>   /*
>    * 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;
> +

On the other hand we can easily get rid of the kernel part by moving 
this check into user space tools, this will minimize the change diff and 
we will still have sane behavior.

What about something like this (completely untested/not compiled) :-

diff --git a/blktrace.c b/blktrace.c
index d0d271f..d6a9f39 100644
--- a/blktrace.c
+++ b/blktrace.c
@@ -2247,6 +2247,9 @@ static int handle_args(int argc, char *argv[])
         if (net_mode == Net_client && net_setup_addr())
                 return 1;

+       /* Check for unsually large numbers for buffers */
+       if (buf_size * buf_nr > BLKTRACE_MAX_ALLOC)
+               return -E2BIG;
         /*
          * Set up for appropriate PFD handler based upon output name.
          */

>   	if (!blk_debugfs_root)
>   		return -ENOENT;
>   
> 





[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux