Subject: Re: Returning a struct from an ioctl
To: None <tech-kern@netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-kern
Date: 04/29/2002 16:07:59
> So, when I call the ioctl I pass a pointer to that structure with the
> row and column fields set.  Then, in the kernel, I fill up the struct
> with the missing data (letter, attributes), and this is what is
> worring me.  As I've been thinking, this may lead to security
> problems, isn't it?  Imagine you pass an invalid pointer to the ioctl
> (well, a pointer that points outside your program).  Then the kernel
> would overwrite the memory it points to without any problem.  Or am I
> wrong?

You're wrong.  Fortunately. :-)

The ioctl machinery deals with this for you, at least one level deep.
The second argument to ioctl has encoded in it the size of the
pointed-to object (this is why you have to give that type when defining
the ioctl); high kernel does a copyin() (for write-style ioctls) before
calling the driver's ioctl routine and does a copyout() (for read-style
ioctls) after - the data pointer passed to the ioctl routine points to
a kernel scratch area; it's not just the pointer userland passed to
ioctl(2).

Now, if the struct itself contains pointers, the ioctl implementation
is responsible for doing the copyin/copyout.  But the first level is
done before the driver has to worry about it.

> BTW, the ioctls are implemented in wsdisplay_cfg_ioctl, that is used
> trought the /dev/ttyEcfg (so it is by default owned by root:wheel, so
> this is not a security problem...)

Yes, that's the other security issue: you have to make sure that this
isn't usable for snooping screen contents.  Sounds as though you ahve
that issue covered.

> How would you do this in a secure way?

Well, as I explained, in this case it's not an issue.  If you had to do
it yourself, you'd use copyin() and/or copyout().

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       mouse@rodents.montreal.qc.ca
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B