[PATCH] Updates for stricter automatic memcpy bounds checking
Arik Nemtsov
arik
Sun Apr 12 00:53:23 PDT 2015
On Sun, Apr 12, 2015 at 3:54 AM, Nick Kralevich <nnk at google.com> wrote:
> Both Android's libc and glibc support _FORTIFY_SOURCE, a compiler
> and libc feature which inserts automatic bounds checking into
> common C functions such as memcpy() and strcpy(). If a buffer
> overflow occurs when calling a hardened libc function, the
> automatic bounds checking will safely shutdown the program and
> prevent memory corruption.
>
> Android is experimenting with _FORTIFY_SOURCE=3, a new fortify
> level which enhances memcpy() to prevent overflowing an element
> of a struct. Under the enhancements, code such as
>
> struct foo {
> char empty[0];
> char one[1];
> char a[10];
> char b[10];
> };
>
> int main() {
> foo myfoo;
> int n = atoi("11");
> memcpy(myfoo.a, "01234567890123456789", n);
> return 0;
> }
>
> will cleanly crash when the memcpy() call is made.
>
> Fixup hostap code to support the new level. Specifically:
>
> * Modify the structures in ieee802_11_defs.h to use ISO C99 flexible
> array members (https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html)
> instead of a zero length array. Zero length arrays have zero length,
> and any attempt to call memcpy() on such elements will always overflow.
> Flexible array members have no such limitation.
>
> * Introduce an extra element into the structure probe_req. This is
> needed to keep the code compiling when an otherwise zero length
> structure would be present.
>
> * Fixup sha1_transform so it works with the enhanced bounds checking.
> The old memcpy() code was attempting to write to context.h0, but that
> structure element is too small and the write was extending (by design)
> into h1, h2, h3, and h4. Use explicit assignments instead of
> overflowing the struct element.
>
> Signed-off-by: Nick Kralevich <nnk at google.com>
> ---
> src/common/ieee802_11_defs.h | 41 +++++++++++++++++++++--------------------
> src/crypto/fips_prf_openssl.c | 16 ++++++++++++----
> 2 files changed, 33 insertions(+), 24 deletions(-)
>
> diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
> index 2e51935..98b249a 100644
> --- a/src/common/ieee802_11_defs.h
> +++ b/src/common/ieee802_11_defs.h
> @@ -470,35 +470,35 @@ struct ieee80211_mgmt {
> le16 auth_transaction;
> le16 status_code;
> /* possibly followed by Challenge text */
> - u8 variable[0];
> + u8 variable[];
> } STRUCT_PACKED auth;
> struct {
> le16 reason_code;
> - u8 variable[0];
> + u8 variable[];
> } STRUCT_PACKED deauth;
> struct {
> le16 capab_info;
> le16 listen_interval;
> /* followed by SSID and Supported rates */
> - u8 variable[0];
> + u8 variable[];
> } STRUCT_PACKED assoc_req;
> struct {
> le16 capab_info;
> le16 status_code;
> le16 aid;
> /* followed by Supported rates */
> - u8 variable[0];
> + u8 variable[];
> } STRUCT_PACKED assoc_resp, reassoc_resp;
> struct {
> le16 capab_info;
> le16 listen_interval;
> u8 current_ap[6];
> /* followed by SSID and Supported rates */
> - u8 variable[0];
> + u8 variable[];
> } STRUCT_PACKED reassoc_req;
> struct {
> le16 reason_code;
> - u8 variable[0];
> + u8 variable[];
> } STRUCT_PACKED disassoc;
> struct {
> u8 timestamp[8];
> @@ -506,11 +506,12 @@ struct ieee80211_mgmt {
> le16 capab_info;
> /* followed by some of SSID, Supported rates,
> * FH Params, DS Params, CF Params, IBSS Params, TIM */
> - u8 variable[0];
> + u8 variable[];
> } STRUCT_PACKED beacon;
> struct {
> + u8 unused;
> /* only variable items: SSID, Supported rates */
> - u8 variable[0];
> + u8 variable[];
> } STRUCT_PACKED probe_req;
Isn't this introducing a bug? This piece of code will now point to the
wrong location I believe:
ie = mgmt->u.probe_req.variable;
Arik
More information about the Hostap
mailing list