[haiku-commits] haiku: hrev56169 - src/libs/compat/openbsd_wlan/net80211

  • From: waddlesplash <waddlesplash@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 9 Jun 2022 17:36:08 +0000 (UTC)

hrev56169 adds 1 changeset to branch 'master'
old head: 5a4ad3a00df5c62d521e9b97262ead5f93d91682
new head: 0bee9ee7118f724ad210230e065d822fb24ba420
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=0bee9ee7118f+%5E5a4ad3a00df5

----------------------------------------------------------------------------

0bee9ee7118f: openbsd_wlan: Refactor implementation of 
IEEE80211_IOC_SCAN_RESULTS.
  
   * Do not allocate an equally-sized buffer for all scan results,
     but just alloca() a buffer for a single result, and copy this
     back to userland at the end of each iteration.
  
   * Check remaining space correctly with respect to IE data.
  
  May fix incorrect scan results or userland memory corruptions
  seen with the previous code. Also should be faster since it
  does not need to allocate large kernel-side temporary buffers.

                              [ Augustin Cavalier <waddlesplash@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev56169
Commit:      0bee9ee7118f724ad210230e065d822fb24ba420
URL:         https://git.haiku-os.org/haiku/commit/?id=0bee9ee7118f
Author:      Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date:        Thu Jun  9 17:35:48 2022 UTC

----------------------------------------------------------------------------

1 file changed, 18 insertions(+), 24 deletions(-)
.../openbsd_wlan/net80211/ieee80211_haiku.cpp    | 42 +++++++++-----------

----------------------------------------------------------------------------

diff --git a/src/libs/compat/openbsd_wlan/net80211/ieee80211_haiku.cpp 
b/src/libs/compat/openbsd_wlan/net80211/ieee80211_haiku.cpp
index 266e99151c..7906c5a6be 100644
--- a/src/libs/compat/openbsd_wlan/net80211/ieee80211_haiku.cpp
+++ b/src/libs/compat/openbsd_wlan/net80211/ieee80211_haiku.cpp
@@ -181,20 +181,15 @@ wlan_control(void* cookie, uint32 op, void* arg, size_t 
length)
                        if (op != SIOCG80211)
                                return B_BAD_VALUE;
 
-                       const int32 count = ireq.i_len / sizeof(struct 
ieee80211req_scan_result);
-                               // ieee80211req_scan_result is variable-length, 
this will get us the max count
-
-                       void* req_scan_result = calloc(1, ireq.i_len);
-                       MemoryDeleter resultDeleter(req_scan_result);
-                       if (!resultDeleter.IsSet())
-                               return B_NO_MEMORY;
-
                        struct ieee80211_nodereq nodereq;
                        struct ieee80211_nodereq_all nodereq_all = {};
 
-                       uint8* out = (uint8*)req_scan_result;
-                       uint16 remaining = ireq.i_len;
-                       for (int i = 0; ; i++) {
+                       // We need a scan_result of maximum possible size to 
work with.
+                       struct ieee80211req_scan_result* sr = (struct 
ieee80211req_scan_result*)
+                               alloca(sizeof(struct ieee80211req_scan_result) 
+ IEEE80211_NWID_LEN + 257);
+
+                       uint16 remaining = ireq.i_len, offset = 0;
+                       for (int i = 0; remaining > 0; i++) {
                                nodereq_all.na_node = &nodereq;
                                nodereq_all.na_size = sizeof(struct 
ieee80211_nodereq);
                                nodereq_all.na_startnode = i;
@@ -207,16 +202,16 @@ wlan_control(void* cookie, uint32 op, void* arg, size_t 
length)
                                if (nodereq_all.na_nodes == 0)
                                        break;
 
-                               int32 required = sizeof(struct 
ieee80211req_scan_result) + nodereq.nr_nwid_len;
+                               int32 size = sizeof(struct 
ieee80211req_scan_result) + nodereq.nr_nwid_len;
                                uint16_t ieLen = 0;
                                if (nodereq.nr_rsnie[1] != 0) {
                                        ieLen = 2 + nodereq.nr_rsnie[1];
-                                       required += ieLen;
+                                       size += ieLen;
                                }
-                               if (remaining < (sizeof(struct 
ieee80211req_scan_result) + nodereq.nr_nwid_len))
+                               const int32 roundedSize = roundup(size, 4);
+                               if (remaining < roundedSize)
                                        break;
 
-                               struct ieee80211req_scan_result* sr = (struct 
ieee80211req_scan_result*)out;
                                sr->isr_ie_off = sizeof(struct 
ieee80211req_scan_result);
                                sr->isr_ie_len = ieLen;
                                sr->isr_freq = 
ieee80211_ieee2mhz(nodereq.nr_channel, nodereq.nr_chan_flags);
@@ -231,15 +226,17 @@ wlan_control(void* cookie, uint32 op, void* arg, size_t 
length)
                                memcpy(sr->isr_rates, nodereq.nr_rates, 
IEEE80211_RATE_MAXSIZE);
                                sr->isr_ssid_len = nodereq.nr_nwid_len;
                                sr->isr_meshid_len = 0;
-                               memcpy(out + sr->isr_ie_off, nodereq.nr_nwid, 
sr->isr_ssid_len);
-                               memcpy(out + sr->isr_ie_off + sr->isr_ssid_len,
-                                       nodereq.nr_rsnie, ieLen);
+                               memcpy((uint8*)sr + sr->isr_ie_off, 
nodereq.nr_nwid, sr->isr_ssid_len);
+                               memcpy((uint8*)sr + sr->isr_ie_off + 
sr->isr_ssid_len, nodereq.nr_rsnie, ieLen);
 
-                               sr->isr_len = roundup(sr->isr_ie_off + 
sr->isr_ssid_len + sr->isr_ie_len, 4);
-                               out += sr->isr_len;
+                               sr->isr_len = roundedSize;
+                               if (user_memcpy((uint8*)ireq.i_data + offset, 
sr, size) != B_OK)
+                                       return B_BAD_ADDRESS;
+
+                               offset += sr->isr_len;
                                remaining -= sr->isr_len;
                        }
-                       ireq.i_len = (out - (uint8*)req_scan_result);
+                       ireq.i_len = offset;
 
                        IFF_LOCKGIANT(ifp);
                        const bigtime_t RAISE_INACT_INTERVAL = 5 * 1000 * 1000 
/* 5s */;
@@ -255,9 +252,6 @@ wlan_control(void* cookie, uint32 op, void* arg, size_t 
length)
                        }
                        IFF_UNLOCKGIANT(ifp);
 
-                       if (user_memcpy(ireq.i_data, req_scan_result, 
ireq.i_len) != B_OK)
-                               return B_BAD_ADDRESS;
-
                        break;
                }
 


Other related posts:

  • » [haiku-commits] haiku: hrev56169 - src/libs/compat/openbsd_wlan/net80211 - waddlesplash