Comment 55 for bug 585938

Revision history for this message
Matt Price (matt-price) wrote : Re: [Bug 585938] Re: 10ec:8171 r8192se_pci + powertop (iwpriv -a) = kernel panic

can't believe this might actually be fixed. As a mere user, what can I
do to help with this? And what versions of ubuntu are currently
affected?

On Wed 08 Aug 2012 10:58:35 AM EDT, gcc wrote:
> OK, I think I understand the problem. The table of iw_priv args and
> functions should alternate SET and GET functions, but Realtek just added
> them all in order.
>
> net/wireless/wext.c uses IW_IS_SET on the command number to determine
> whether it's a GET or SET command, and this just checks the last bit. So
> it's essential that GET commands have an odd command number. Otherwise
> ioctl_private_iw_point won't allocate a memory buffer to pass into the
> handler.
>
> r8192_wx_get_adhoc_peers is an iwpriv ioctl that behaves as a GET ioctl,
> it expects a writable buffer from the wireless extensions system
> (wext.c) and it writes all over it. However it lives in a SET slot
> (SIOCIWFIRSTPRIV + 0xc is even) so the kernel hasn't allocated any
> memory to it (extra_size = 0), although kzalloc did apparently return a
> valid pointer or this would have been a null pointer reference. Anyway
> at this point the driver will scribble over random kernel memory and
> cause a panic soon after.
>
> It's not clear to me why reducing the buffer size works for some people.
> Perhaps the pointer returned by kzalloc happens to be a memory location
> big enough to write 1024 bytes to, for them but not for me?
>
> The fix appears to be to correct the allocation of iwpriv ioctl numbers
> in the driver. I'm going to try my hand at writing a patch for this.
> Newer kernels (3.2.0) appear to have a completely different driver model
> based on nl80211 instead of wext, so I can't just backport a patch.
>
> It would also probably be helpful in debugging other drivers if wext.c
> (1) checked that (apparent) SET ioctls don't expect a GET buffer, and
> GET ioctls don't expect a SET buffer, or return an error if they do, and
> (2) set the data pointer to 0 instead of calling kzalloc for 0 bytes.
>