[dm-devel] [PATCH 2/3] dm-ioctl: fix unsafe use of dm_ioctl.data_size
Mikulas Patocka
mpatocka at redhat.com
Fri Dec 7 02:53:11 UTC 2012
Yes, it's ok.
Acked-by: Mikulas Patocka <mpatocka at redhat.com>
On Thu, 6 Dec 2012, Alasdair G Kergon wrote:
> I don't think we need to support the situation when the value changes during
> the copying of the parameters, so how about something more like this instead?
>
> Alasdair
>
>
> From: Alasdair G Kergon <agk at redhat.com>
>
> Abort dm ioctl processing if userspace changes the data_size parameter
> after we validated it but before we finished copying the data buffer
> from userspace.
>
> The dm ioctl parameters are processed in the following sequence:
> 1. ctl_ioctl() calls copy_params();
> 2. copy_params() makes a first copy of the fixed-sized portion of the
> userspace parameters into the local variable "tmp";
> 3. copy_params() then validates tmp.data_size and allocates a new
> structure big enough to hold the complete data and copies the whole
> userspace buffer there;
> 4. ctl_ioctl() reads userspace data the second time and copies the whole
> buffer into the pointer "param";
> 5. ctl_ioctl() reads param->data_size without any validation and stores it
> in the variable "input_param_size";
> 6. "input_param_size" is further used as the authoritative size of the
> kernel buffer.
>
> The problem is that userspace code could change the contents of user
> memory between steps 2 and 4. In particular, the data_size parameter
> can be changed to an invalid value after the kernel has validated it.
> This lets userspace force the kernel to access invalid kernel memory.
>
> The fix is to ensure that the size has not changed at step 4.
>
> This patch shouldn't have a security impact because CAP_SYS_ADMIN is
> required to run this code, but it should be fixed anyway.
>
> Reported-by: Mikulas Patocka <mpatocka at redhat.com>
> Signed-off-by: Alasdair G Kergon <agk at redhat.com>
> Cc: stable at kernel.org
>
> ---
> drivers/md/dm-ioctl.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> Index: linux/drivers/md/dm-ioctl.c
> ===================================================================
> --- linux.orig/drivers/md/dm-ioctl.c
> +++ linux/drivers/md/dm-ioctl.c
> @@ -1566,6 +1566,14 @@ static int copy_params(struct dm_ioctl _
> if (copy_from_user(dmi, user, tmp.data_size))
> goto bad;
>
> + /*
> + * Abort if something changed the ioctl data while it was being copied.
> + */
> + if (dmi->data_size != tmp.data_size) {
> + DMERR("rejecting ioctl: data size modified while processing parameters");
> + goto bad;
> + }
> +
> /* Wipe the user buffer so we do not return it to userspace */
> if (secure_data && clear_user(user, tmp.data_size))
> goto bad;
>
More information about the dm-devel
mailing list