lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1173364747.14001.7.camel@johannes.berg>
Date:	Thu, 08 Mar 2007 15:39:07 +0100
From:	Johannes Berg <johannes@...solutions.net>
To:	jt@....hp.com
Cc:	Michael Buesch <mb@...sch.de>, linux-wireless@...r.kernel.org,
	netdev <netdev@...r.kernel.org>, Jeff Garzik <jgarzik@...ox.com>,
	Dan Williams <dcbw@...hat.com>,
	Jouni Malinen <jkm@...icescape.com>
Subject: Re: wireless extensions vs. 64-bit architectures

On Tue, 2007-03-06 at 18:03 -0800, Jean Tourrilhes wrote:

> 	Ok, please check the patch attached. I don't have a box to
> test that on, and on my 32 bit kernel it is not even compiled, but I
> believe I got everything all right.

Don't I wish it was that easy... Granted, that does seem to fix the
issue with iw_point but that's not the only thing that's broken. Here's
the next thing, I think this only happens after applying that patch,
without it probably just craps out earlier. Same thing happens with
iwevent (and maybe other things too.)

Enabling debugging in wireless tools yields (on my 64-bit kernel with
32-bit userland):
# LD_LIBRARY_PATH=.  ./iwlist wlan0 scan
Scan result 4096
[00:18:8B:15:50:8A:35:E0:00:01:00:C0:02:E1:B8:0E:C0:00:00:00:50:8A:35:F0:00:19:8B:1B:50:8A:35:E0:00:09:00:01:50:8A:35:F0:47:6F:6C:6F:73:4E:65:74:7A:00:18:8B:01:50:8A:35:E0:49:45:45:45:20:38:30:32:2E:31:31:62:67:00:35:F0:00:0C:8B:07:50:8A:35:E0:00:00:00:03:00:10:8B:05:50:8A:35:E0:00:00:00:07:00:00:00:32:00:10:8B:2B:50:8A:35:E0:00:00:08:00:67:00:35:F0:00:70:8B:21:50:8A:35:E0:00:0F:42:40:00:00:00:32:00:1E:84:80:00:00:00:32:00:53:EC:60:00:00:00:32:00:5B:8D:80:00:00:00:32:00:89:54:40:00:00:00:32:00:A7:D8:C0:00:00:00:<lots more zeroes>
wlan0     Scan completed : 
DBG - stream->current = 0x10019008, stream->value = (nil), stream->end = 0x1001a008
DBG - iwe->cmd = 0x8B15, iwe->len = 24

                         ^^^^^^^^^^^^^ that's already bogus


DBG - event_type = 6, event_len = 16, pointer = 0x1001900c
          Cell 01 - Address: 35:E0:00:01:00:C0 
DBG - stream->current = 0x10019020, stream->value = (nil), stream->end = 0x1001a008
DBG - iwe->cmd = 0x8B1B, iwe->len = 25
DBG - event_type = 8, event_len = 4, pointer = 0x10019024 
DBG - extra_len = 17, token_len = 20618, token = 20618, max = 33, min = 0
                    ESSID:"" [224] 
DBG - stream->current = 0x10019039, stream->value = (nil), stream->end = 0x1001a008
DBG - iwe->cmd = 0x8B01, iwe->len = 24
DBG - event_type = 2, event_len = 16, pointer = 0x1001903d
                    Protocol:P�5�IEEE 802.11b 
DBG - stream->current = 0x10019051, stream->value = (nil), stream->end = 0x1001a008
DBG - iwe->cmd = 0x8B07, iwe->len = 12 
DBG - event_type = 4, event_len = 4, pointer = 0x10019055
Segmentation fault

Ooops.

Whereas on a 32-bit machine in the same environment it is as it should
be:

Scan result 264
[00:14:8B:15:00:01:00:C0:02:E1:B8:0E:C0:02:5A:F4:9F:CF:18:C0:00:11:8B:1B:00:09:00:01:47:6F:6C:6F:73:4E:65:74:7A:00:14:8B:01:49:45:45:45:20:38:30:32:2E:31:31:62:67:00:18:C0:00:08:8B:07:00:00:00:03:00:0C:8B:05:00:00:00:07:00:00:00:32:00:08:8B:2B:00:00:08:00:00:6C:8B:21:00:0F:42:40:00:00:08:00:00:1E:84:80:00:00:08:00:00:53:EC:60:00:00:08:00:00:5B:8D:80:00:00:08:00:00:89:54:40:00:00:08:00:00:A7:D8:C0:00:00:08:00:00:B7:1B:00:00:00:08:00:01:12:A8:80:00:00:08:00:01:4F:B1:80:00:00:08:00:01:6E:36:00:00:00:08:00:02:25:51:00:00:00:08:00:02:DC:6C:00:00:00:08:00:03:37:F9:80:00:00:08:00:00:08:8C:01:64:00:00:47:00:20:8C:05:00:18:00:00:DD:16:00:50:F2:01:01:00:00:50:F2:02:01:00:00:50:F2:02:01:00:00:50:F2:02:00:1F:8C:02:00:17:00:00:20:4C:61:73:74:20:62:65:61:63:6F:6E:3A:20:32:32:30:6D:73:20:61:67:6F]
eth2      Scan completed : 
DBG - stream->current = 0x10019008, stream->value = (nil), stream->end = 0x10019110
DBG - iwe->cmd = 0x8B15, iwe->len = 20 

                         ^^^^^^^^^^^^^ look, 4 bytes less. I wonder why that is!


DBG - event_type = 6, event_len = 16, pointer = 0x1001900c
          Cell 01 - Address: 00:C0:02:E1:B8:0E 
DBG - stream->current = 0x1001901c, stream->value = (nil), stream->end = 0x10019110
[and lots more skipped for clarity]


So there. Do you want to know why too?

Let's look at a debug info dump from my 64-bit kernel:

 <1><96de>: Abbrev Number: 33 (DW_TAG_structure_type)
  <96df>     DW_AT_sibling     : <9717>
  <96e3>     DW_AT_name        : (indirect string, offset: 0x4278): iw_event
  <96e7>     DW_AT_byte_size   : 24
  <96e8>     DW_AT_decl_file   : 225
  <96e9>     DW_AT_decl_line   : 1064
 <2><96eb>: Abbrev Number: 23 (DW_TAG_member)
  <96ec>     DW_AT_name        : len
  <96f0>     DW_AT_decl_file   : 225
  <96f1>     DW_AT_decl_line   : 1065
  <96f3>     DW_AT_type        : <ed>
  <96f7>     DW_AT_data_member_location: 2 byte block: 23 0     (DW_OP_plus_uconst: 0)
 <2><96fa>: Abbrev Number: 23 (DW_TAG_member)
  <96fb>     DW_AT_name        : cmd
  <96ff>     DW_AT_decl_file   : 225
  <9700>     DW_AT_decl_line   : 1066
  <9702>     DW_AT_type        : <ed>
  <9706>     DW_AT_data_member_location: 2 byte block: 23 2     (DW_OP_plus_uconst: 2)
 <2><9709>: Abbrev Number: 23 (DW_TAG_member)
  <970a>     DW_AT_name        : u
  <970c>     DW_AT_decl_file   : 225
  <970d>     DW_AT_decl_line   : 1067
  <970f>     DW_AT_type        : <956e>
  <9713>     DW_AT_data_member_location: 2 byte block: 23 8     (DW_OP_plus_uconst: 8)


The same structure from the 32-bit user space program (iwlist):

 <1><c3a>: Abbrev Number: 15 (DW_TAG_structure_type)
  <c3b>     DW_AT_sibling     : <c73>
  <c3f>     DW_AT_name        : (indirect string, offset: 0x32b): iw_event
  <c43>     DW_AT_byte_size   : 20
  <c44>     DW_AT_decl_file   : 96
  <c45>     DW_AT_decl_line   : 1095
 <2><c47>: Abbrev Number: 16 (DW_TAG_member)
  <c48>     DW_AT_name        : len
  <c4c>     DW_AT_decl_file   : 96
  <c4d>     DW_AT_decl_line   : 1096
  <c4f>     DW_AT_type        : <550>
  <c53>     DW_AT_data_member_location: 2 byte block: 23 0      (DW_OP_plus_uconst: 0)
 <2><c56>: Abbrev Number: 16 (DW_TAG_member)
  <c57>     DW_AT_name        : cmd
  <c5b>     DW_AT_decl_file   : 96
  <c5c>     DW_AT_decl_line   : 1097
  <c5e>     DW_AT_type        : <550>
  <c62>     DW_AT_data_member_location: 2 byte block: 23 2      (DW_OP_plus_uconst: 2)
 <2><c65>: Abbrev Number: 16 (DW_TAG_member)
  <c66>     DW_AT_name        : u
  <c68>     DW_AT_decl_file   : 96
  <c69>     DW_AT_decl_line   : 1098
  <c6b>     DW_AT_type        : <7e0>
  <c6f>     DW_AT_data_member_location: 2 byte block: 23 4      (DW_OP_plus_uconst: 4)

Compare the last lines of both (I'd have posted pahole output but the
dwarf lib it uses doesn't parse 64-bit binaries correctly when it is
compiled as a 32-bit binary.) 

Now look at the definition of IW_EV_LCP_LEN. Or wait, how about we look
at the comment in front of it:

  /* Size of the Event prefix (including padding and alignement junk) */


Now, I don't know what gcc for ia64 does and I don't have a cross
compiler to check, but on powerpc it does this. I think the reason for
this here is iw_point again since it is part of the union iwreq_data
which means that the whole union requires 8-byte alignment on 64-bit
architectures where it's part of struct iw_event.

The easiest "fix" would be to make the structure packed, but existing
64-bit userspace expects the struct with padding while existing 32-bit
userspace (which of course includes 32-bit userspace running on 64-bit
machines) expects no padding... So that "fix" breaks all 64-bit
userspace, great.

Oh, btw, this also means that we have an information leak on 64-bit
kernels. Those alignment bytes aren't ever cleared or anything, they
come right from the stack since most users of this just use a struct
iw_event on the stack which is then memcpy()ed right into the userspace
buffer. For example those bytes 5 through 8 ("50:8A:35:E0") in the first
buffer above. This is generally considered a security problem.

Have fun...

johannes

Download attachment "signature.asc" of type "application/pgp-signature" (191 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ