Date: Mon, 12 Apr 2010 18:45:57 -0700 From: Alfred Perlstein <alfred@freebsd.org> To: d@delphij.net Cc: freebsd-arch@freebsd.org Subject: Re: _IOWR when errno != 0 Message-ID: <20100413014557.GE19003@elvis.mu.org> In-Reply-To: <4BC3BA48.9010009@delphij.net> References: <4BC39E93.7060906@delphij.net> <20100412233330.GC19003@elvis.mu.org> <4BC3BA48.9010009@delphij.net>
next in thread | previous in thread | raw e-mail | index | archive | help
* Xin LI <delphij@delphij.net> [100412 17:27] wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > On 2010/04/12 16:33, Alfred Perlstein wrote: > > * Xin LI <delphij@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100413014557.GE19003>