_IOWR when errno != 0
Alfred Perlstein
alfred at freebsd.org
Tue Apr 13 01:45:57 UTC 2010
* Xin LI <delphij at delphij.net> [100412 17:27] wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 2010/04/12 16:33, Alfred Perlstein wrote:
> > * Xin LI <delphij at delphij.net> [100412 15:28] wrote:
> >> -----BEGIN PGP SIGNED MESSAGE-----
> >> Hash: SHA1
> >>
> >> Hi,
> >>
> >> Is there a sane way to copyout ioctl request when the returning errno !=
> >> 0? Looking at the code, currently, in sys/kern/sys_generic.c, we have:
> >>
> >> ===========
> >> error = kern_ioctl(td, uap->fd, com, data);
> >>
> >> if (error == 0 && (com & IOC_OUT))
> >> error = copyout(data, uap->data, (u_int)size);
> >> ===========
> >>
> >> Is there any objection if I change it to something like:
> >>
> >> ===========
> >> saved_error = kern_ioctl(td, uap->fd, com, data);
> >>
> >> if (com & IOC_OUT)
> >> error = copyout(data, uap->data, (u_int)size);
> >> if (saved_error)
> >> error = saved_error;
> >> ===========
> >
> > Is this for linux compat?
>
> Do they do this way? I'm not quite sure :-/
>
> I got a bug report and am thinking about how to fix it, it seems that we
> do not have a generic way of returning an error number while giving some
> "hints" about the error at the same time, for the ioctl() call. Adding
> an extra pointer to the request structure seems to be a last-resort way
> and sounds to be ugly.
Why not just have the ioctl return success but have an error code
inside the result, example:
struct yourioctldata {
int error; // 0 = ok, else errno
char data[DATASIZE]; // data..
...
}
>
> > I'm not sure this would work, it might seriously break userland
> > compat. Have you looked around/queiried what the expected outcome
> > is from a bad ioctl? By default the buffer will be zero'd this
> > might be unexpected by apps. (all or nothing)
>
> Yes that's exactly why I'm asking, my understanding is that for normal
> usages would be something like:
>
> if (ioctl(fd, SIOCSOMETHING, &req) < 0) {
> // do something to handle the error
> } else {
> // use data fed back from req
> }
>
> In this case, I think the result would not be affected. Is there many
> (if any) programs that don't bother to check return value of ioctl()?
>
> Speaking for the userland buffer, for _IOR ioctls, the side effect would
> be that userland would see a zeroed out 'req' structure (kernel buffer
> gets zeroed out before calling kern_ioctl), or "half-baked" one (the
> kernel code may have only written partial data). For _IOWR ioctls, the
> side effect would be that the userland may get half-baked data.
>
> The in-kernel request buffer is always initialized, as it is either
> overwritten by copyin(), or by bzero() so I don't think sensitive data
> could be leaked, unless the kernel code intentionally copy some
> sensitive data to the req buffer, detect if there is error, and then
> scrub sensitive data away.
I'm not sure and certainly not an authority on this. It's probably
worth pinging a few of the standards people.
This is interesting, good luck!
--
- Alfred Perlstein
.- AMA, VMOA #5191, 03 vmax, 92 gs500, 85 ch250
.- FreeBSD committer
More information about the freebsd-arch
mailing list