* [PATCH] wext: verify buffer size for SIOCSIWENCODEEXT
@ 2009-05-13 10:04 Johannes Berg
2009-05-13 22:00 ` [PATCH v2] " Johannes Berg
0 siblings, 1 reply; 2+ messages in thread
From: Johannes Berg @ 2009-05-13 10:04 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
Another design flaw in wireless extensions (is anybody
surprised?) in the way it handles the iw_encode_ext
structure: The structure is part of the 'extra' memory
but contains the key length explicitly, instead of it
just being the length of the extra buffer - size of
the struct and using the explicit key length only for
the get operation (which only writes it).
Therefore, we have this layout:
extra: +-------------------------+
| struct iw_encode_ext { |
| ... |
| u16 key_len; |
| u8 key[0]; |
| }; |
+-------------------------+
| key material |
+-------------------------+
Now, all drivers I checked use ext->key_len without
checking that both key_len and the struct fit into the
extra buffer that has been copied from userspace. This
leads to a buffer overrun while reading that buffer,
depending on the driver it may be possible to specify
arbitrary key_len or it may need to be a proper length
for the key algorithm specified.
Thankfully, this is only exploitable by root, but root
can actually cause a segfault or use kernel memory as
a key (which you can even get back with siocgiwencode
or siocgiwencodeext from the key buffer).
Fix this by verifying that key_len fits into the buffer
along with struct iw_encode_ext.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
net/wireless/wext.c | 7 +++++++
1 file changed, 7 insertions(+)
--- wireless-testing.orig/net/wireless/wext.c 2009-05-13 11:47:04.000000000 +0200
+++ wireless-testing/net/wireless/wext.c 2009-05-13 11:47:25.000000000 +0200
@@ -798,6 +798,13 @@ static int ioctl_standard_iw_point(struc
err = -EFAULT;
goto out;
}
+
+ if (cmd == SIOCSIWENCODEEXT) {
+ struct iw_encode_ext *ee = extra;
+
+ if (iwp->length < sizeof(*ee) + ee->key_len)
+ return -EFAULT;
+ }
}
err = handler(dev, info, (union iwreq_data *) iwp, extra);
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH v2] wext: verify buffer size for SIOCSIWENCODEEXT
2009-05-13 10:04 [PATCH] wext: verify buffer size for SIOCSIWENCODEEXT Johannes Berg
@ 2009-05-13 22:00 ` Johannes Berg
0 siblings, 0 replies; 2+ messages in thread
From: Johannes Berg @ 2009-05-13 22:00 UTC (permalink / raw)
To: John Linville; +Cc: linux-wireless
Another design flaw in wireless extensions (is anybody
surprised?) in the way it handles the iw_encode_ext
structure: The structure is part of the 'extra' memory
but contains the key length explicitly, instead of it
just being the length of the extra buffer - size of
the struct and using the explicit key length only for
the get operation (which only writes it).
Therefore, we have this layout:
extra: +-------------------------+
| struct iw_encode_ext { |
| ... |
| u16 key_len; |
| u8 key[0]; |
| }; |
+-------------------------+
| key material |
+-------------------------+
Now, all drivers I checked use ext->key_len without
checking that both key_len and the struct fit into the
extra buffer that has been copied from userspace. This
leads to a buffer overrun while reading that buffer,
depending on the driver it may be possible to specify
arbitrary key_len or it may need to be a proper length
for the key algorithm specified.
Thankfully, this is only exploitable by root, but root
can actually cause a segfault or use kernel memory as
a key (which you can even get back with siocgiwencode
or siocgiwencodeext from the key buffer).
Fix this by verifying that key_len fits into the buffer
along with struct iw_encode_ext.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
Forgot a cast, not sure why that didn't show up in my other compile
test?!
net/wireless/wext.c | 7 +++++++
1 file changed, 7 insertions(+)
--- wireless-testing.orig/net/wireless/wext.c 2009-05-13 23:56:22.000000000 +0200
+++ wireless-testing/net/wireless/wext.c 2009-05-13 23:56:32.000000000 +0200
@@ -798,6 +798,13 @@ static int ioctl_standard_iw_point(struc
err = -EFAULT;
goto out;
}
+
+ if (cmd == SIOCSIWENCODEEXT) {
+ struct iw_encode_ext *ee = (void *) extra;
+
+ if (iwp->length < sizeof(*ee) + ee->key_len)
+ return -EFAULT;
+ }
}
err = handler(dev, info, (union iwreq_data *) iwp, extra);
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-05-13 22:00 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-13 10:04 [PATCH] wext: verify buffer size for SIOCSIWENCODEEXT Johannes Berg
2009-05-13 22:00 ` [PATCH v2] " Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox