Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Apr 2010 17:26:48 -0700
From:      Xin LI <delphij@delphij.net>
To:        Alfred Perlstein <alfred@freebsd.org>
Cc:        d@delphij.net, freebsd-arch@freebsd.org
Subject:   Re: _IOWR when errno != 0
Message-ID:  <4BC3BA48.9010009@delphij.net>
In-Reply-To: <20100412233330.GC19003@elvis.mu.org>
References:  <4BC39E93.7060906@delphij.net> <20100412233330.GC19003@elvis.mu.org>

next in thread | previous in thread | raw e-mail | index | archive | help
-----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.

> 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.

Cheers,
- -- 
Xin LI <delphij@delphij.net>	http://www.delphij.net/
FreeBSD - The Power to Serve!	       Live free or die
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (FreeBSD)

iQEcBAEBAgAGBQJLw7pIAAoJEATO+BI/yjfBXjwH/RaheqNyhY0eECcqC5Gz0ycm
2VOpHoe+oRpwHNDYrlNqILKl815HTjpvyi145IpMPIKvEct2O0i6wGJ3FH7VFQwP
ucZh6Tj3K3yF+OsFw3iAk69aqFhslb/SuZtuAbJAA4DB+H1rUPtEfWs9y8XjmAaS
ZvFTmmP1w1V50I843UJEbY86LqwJGOgGH0mJ6n1mEsLOFyrASrjGajAOb/mEvju4
pLVoaKI9sWGk4QfE9QKol083DuSC/WVbJBFHmzN0K0sNmRfyZofcSIYpWDMkwS4n
Mt2M3b6irwul83EkK+cw1gclmV7lUTslfMGtyLbLahZek3HFDh4oZ5xnctfI1xA=
=1Hn6
-----END PGP SIGNATURE-----



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4BC3BA48.9010009>