Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 20 Jan 2013 16:59:39 -0800
From:      mdf@FreeBSD.org
To:        Yuri <yuri@rawbw.com>
Cc:        hackers@freebsd.org
Subject:   Re: How to validate the variable size memory block in ioctl handler?
Message-ID:  <CAMBSHm8-zJpTN_D2SGSYwX%2BEbituDmw7S9di1phKxEC_OL%2Bu=A@mail.gmail.com>
In-Reply-To: <50FC7767.4050207@rawbw.com>
References:  <50FC7767.4050207@rawbw.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, Jan 20, 2013 at 3:01 PM, Yuri <yuri@rawbw.com> wrote:
> I am implementing an ioctl that reads/writes variable size structure.
> Allocated size is supplied by the caller in the structure itself.
> struct my_struct {
>   int len; // allocated size
>   other_struct s[1];
> };
> ioctl request id is defined as _IOWR('X', <number>, my_struct)
>
> How to validate from the ioctl function handler (for some device) that the
> whole (variable size) block of bytes is RW accessible in the process memory
> space?
> Should I call copyout/copyin for this, or there is some shorter way?
> EFAULT should be returned in case of validation failure.
>
> As I understand, macros like _IOR, _IOWR do validation based on the size of
> structure supplied to them. So that the handler procedures don't have to do
> that.
> I was expecting to find among them some macro that would work for such
> variable size structure, but it isn't there. (Not sure if this is possible
> language-wise).

You'll need to pass in more than the above, probably, as the kernel's
ioctl() function has copied in the specified number of bytes already.
I.e. the value passed to your ioctl handler is already in the kernel
space, and unless it's 4 bytes, was malloc(9)'d and copyin'd (if it's
an IN parameter).  The size used is the size passed to the _IOC()
macro.

To do what you want it sounds like you want your handler to take something like:

struct var_ioctl {
    int len;
    void *data;
};

Then then handler itself would have to use copyin/copyout to access
the data.  There's no simpler way.

Cheers,
matthew



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAMBSHm8-zJpTN_D2SGSYwX%2BEbituDmw7S9di1phKxEC_OL%2Bu=A>