Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-7]: src/external/bsd/wpa/dist/src Pull up following revision(s) (...



details:   https://anonhg.NetBSD.org/src/rev/c2c0a15f042b
branches:  netbsd-7
changeset: 799300:c2c0a15f042b
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Mon May 11 04:51:51 2015 +0000

description:
Pull up following revision(s) (requested by christos in ticket #749):
        external/bsd/wpa/dist/src/ap/wmm.c: revision 1.2
        external/bsd/wpa/dist/src/wps/httpread.c: revision 1.2
        external/bsd/wpa/dist/src/eap_server/eap_server_pwd.c: revision 1.2-1.3
        external/bsd/wpa/dist/src/eap_peer/eap_pwd.c: revision 1.2-1.4
- strtoul() return value may end up overflowing the int h->chunk_size and
  resulting in a negative value to be stored as the chunk_size. This could
  result in the following memcpy operation using a very large length
  argument which would result in a buffer overflow and segmentation fault.

  This could have been used to cause a denial service by any device that
  has been authorized for network access (either wireless or wired). This
  would affect both the WPS UPnP functionality in a WPS AP (hostapd with
  upnp_iface parameter set in the configuration) and WPS ER
  (wpa_supplicant with WPS_ER_START control interface command used).
  Validate the parsed chunk length value to avoid this. In addition to
  rejecting negative values, we can also reject chunk size that would be
  larger than the maximum configured body length.
  Thanks to Kostya Kortchinsky of Google security team for discovering and
  reporting this issue.

- The length of the WMM Action frame was not properly validated and the
  length of the information elements (int left) could end up being
  negative. This would result in reading significantly past the stack
  buffer while parsing the IEs in ieee802_11_parse_elems() and while doing
  so, resulting in segmentation fault.

  This can result in an invalid frame being used for a denial of service
  attack (hostapd process killed) against an AP with a driver that uses
  hostapd for management frame processing (e.g., all mac80211-based
  drivers).

  Thanks to Kostya Kortchinsky of Google security team for discovering and
  reporting this issue.

- The length of the received Commit and Confirm message payloads was not
  checked before reading them. This could result in a buffer read
  overflow when processing an invalid message.

  Fix this by verifying that the payload is of expected length before
  processing it. In addition, enforce correct state transition sequence to
  make sure there is no unexpected behavior if receiving a Commit/Confirm
  message before the previous exchanges have been completed.

  Thanks to Kostya Kortchinsky of Google security team for discovering and
  reporting this issue.

- The remaining number of bytes in the message could be smaller than the
  Total-Length field size, so the length needs to be explicitly checked
  prior to reading the field and decrementing the len variable. This could
  have resulted in the remaining length becoming negative and interpreted
  as a huge positive integer.

  In addition, check that there is no already started fragment in progress
  before allocating a new buffer for reassembling fragments. This avoid a
  potential memory leak when processing invalid message.

- The L (Length) and M (More) flags needs to be cleared before deciding
  whether the locally generated response requires fragmentation. This
  fixes an issue where these flags from the server could have been invalid
  for the following message. In some cases, this could have resulted in
  triggering the wpabuf security check that would terminate the process
  due to invalid buffer allocation.

diffstat:

 external/bsd/wpa/dist/src/ap/wmm.c                    |   3 +
 external/bsd/wpa/dist/src/eap_peer/eap_pwd.c          |  30 +++++++++++++++++++
 external/bsd/wpa/dist/src/eap_server/eap_server_pwd.c |  22 +++++++++++++
 external/bsd/wpa/dist/src/wps/httpread.c              |   7 ++++
 4 files changed, 62 insertions(+), 0 deletions(-)

diffs (136 lines):

diff -r 401d688f4e72 -r c2c0a15f042b external/bsd/wpa/dist/src/ap/wmm.c
--- a/external/bsd/wpa/dist/src/ap/wmm.c        Mon May 11 03:33:46 2015 +0000
+++ b/external/bsd/wpa/dist/src/ap/wmm.c        Mon May 11 04:51:51 2015 +0000
@@ -274,6 +274,9 @@
                return;
        }
 
+       if (left < 0)
+               return; /* not a valid WMM Action frame */
+
        /* extract the tspec info element */
        if (ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) {
                hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
diff -r 401d688f4e72 -r c2c0a15f042b external/bsd/wpa/dist/src/eap_peer/eap_pwd.c
--- a/external/bsd/wpa/dist/src/eap_peer/eap_pwd.c      Mon May 11 03:33:46 2015 +0000
+++ b/external/bsd/wpa/dist/src/eap_peer/eap_pwd.c      Mon May 11 04:51:51 2015 +0000
@@ -301,6 +301,23 @@
        BIGNUM *mask = NULL, *x = NULL, *y = NULL, *cofactor = NULL;
        u16 offset;
        u8 *ptr, *scalar = NULL, *element = NULL;
+       size_t prime_len, order_len;
+
+       if (data->state != PWD_Commit_Req) {
+               ret->ignore = TRUE;
+               goto fin;
+       }
+
+       prime_len = BN_num_bytes(data->grp->prime);
+       order_len = BN_num_bytes(data->grp->order);
+
+       if (payload_len != 2 * prime_len + order_len) {
+               wpa_printf(MSG_INFO,
+                          "EAP-pwd: Unexpected Commit payload length %u (expected %u)",
+                          (unsigned int) payload_len,
+                          (unsigned int) (2 * prime_len + order_len));
+               goto fin;
+       }
 
        if (((data->private_value = BN_new()) == NULL) ||
            ((data->my_element = EC_POINT_new(data->grp->group)) == NULL) ||
@@ -783,11 +800,23 @@
         * if it's the first fragment there'll be a length field
         */
        if (EAP_PWD_GET_LENGTH_BIT(lm_exch)) {
+               if (len < 2) {
+                       wpa_printf(MSG_DEBUG,
+                                  "EAP-pwd: Frame too short to contain Total-Length field");
+                       ret->ignore = TRUE;
+                       return NULL;
+               }
                tot_len = WPA_GET_BE16(pos);
                wpa_printf(MSG_DEBUG, "EAP-pwd: Incoming fragments whose "
                           "total length = %d", tot_len);
                if (tot_len > 15000)
                        return NULL;
+               if (data->inbuf) {
+                       wpa_printf(MSG_DEBUG,
+                                  "EAP-pwd: Unexpected new fragment start when previous fragment is still in use");
+                       ret->ignore = TRUE;
+                       return NULL;
+               }
                data->inbuf = wpabuf_alloc(tot_len);
                if (data->inbuf == NULL) {
                        wpa_printf(MSG_INFO, "Out of memory to buffer "
@@ -874,6 +903,7 @@
         * we have output! Do we need to fragment it?
         */
        len = wpabuf_len(data->outbuf);
+       lm_exch = EAP_PWD_GET_EXCHANGE(lm_exch);
        if ((len + EAP_PWD_HDR_SIZE) > data->mtu) {
                resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PWD, data->mtu,
                                     EAP_CODE_RESPONSE, eap_get_id(reqData));
diff -r 401d688f4e72 -r c2c0a15f042b external/bsd/wpa/dist/src/eap_server/eap_server_pwd.c
--- a/external/bsd/wpa/dist/src/eap_server/eap_server_pwd.c     Mon May 11 03:33:46 2015 +0000
+++ b/external/bsd/wpa/dist/src/eap_server/eap_server_pwd.c     Mon May 11 04:51:51 2015 +0000
@@ -634,9 +634,21 @@
        BIGNUM *x = NULL, *y = NULL, *cofactor = NULL;
        EC_POINT *K = NULL, *point = NULL;
        int res = 0;
+       size_t prime_len, order_len;
 
        wpa_printf(MSG_DEBUG, "EAP-pwd: Received commit response");
 
+       prime_len = BN_num_bytes(data->grp->prime);
+       order_len = BN_num_bytes(data->grp->order);
+
+       if (payload_len != 2 * prime_len + order_len) {
+               wpa_printf(MSG_INFO,
+                          "EAP-pwd: Unexpected Commit payload length %u (expected %u)",
+                          (unsigned int) payload_len,
+                          (unsigned int) (2 * prime_len + order_len));
+               goto fin;
+       }
+
        if (((data->peer_scalar = BN_new()) == NULL) ||
            ((data->k = BN_new()) == NULL) ||
            ((cofactor = BN_new()) == NULL) ||
@@ -901,11 +913,21 @@
         * the first fragment has a total length
         */
        if (EAP_PWD_GET_LENGTH_BIT(lm_exch)) {
+               if (len < 2) {
+                       wpa_printf(MSG_DEBUG,
+                                  "EAP-pwd: Frame too short to contain Total-Length field");
+                       return;
+               }
                tot_len = WPA_GET_BE16(pos);
                wpa_printf(MSG_DEBUG, "EAP-pwd: Incoming fragments, total "
                           "length = %d", tot_len);
                if (tot_len > 15000)
                        return;
+               if (data->inbuf) {
+                       wpa_printf(MSG_DEBUG,
+                                  "EAP-pwd: Unexpected new fragment start when previous fragment is still in use");
+                       return;
+               }
                data->inbuf = wpabuf_alloc(tot_len);
                if (data->inbuf == NULL) {
                        wpa_printf(MSG_INFO, "EAP-pwd: Out of memory to "
diff -r 401d688f4e72 -r c2c0a15f042b external/bsd/wpa/dist/src/wps/httpread.c
--- a/external/bsd/wpa/dist/src/wps/httpread.c  Mon May 11 03:33:46 2015 +0000
+++ b/external/bsd/wpa/dist/src/wps/httpread.c  Mon May 11 04:51:51 2015 +0000
@@ -533,6 +533,13 @@
                                        if (!isxdigit(*cbp))
                                                goto bad;
                                        h->chunk_size = strtoul(cbp, NULL, 16);
+                                       if (h->chunk_size < 0 ||
+                                           h->chunk_size > h->max_bytes) {
+                                               wpa_printf(MSG_DEBUG,
+                                                          "httpread: Invalid chunk size %d",
+                                                          h->chunk_size);
+                                               goto bad;
+                                       }
                                        /* throw away chunk header
                                         * so we have only real data
                                         */



Home | Main Index | Thread Index | Old Index