_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