LVS
lvs-devel
Google
 
Web LinuxVirtualServer.org

[PATCH 3/4] staging: rtl8712: reduce stack usage, again

To: Kees Cook <keescook@xxxxxxxxxxxx>, Larry Finger <Larry.Finger@xxxxxxxxxxxx>, Florian Schilhabel <florian.c.schilhabel@xxxxxxxxxxxxxx>, Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
Subject: [PATCH 3/4] staging: rtl8712: reduce stack usage, again
Cc: James Smart <james.smart@xxxxxxxxxxxx>, Dick Kennedy <dick.kennedy@xxxxxxxxxxxx>, "James E . J . Bottomley" <jejb@xxxxxxxxxxxxx>, "Martin K . Petersen" <martin.petersen@xxxxxxxxxx>, "David S . Miller" <davem@xxxxxxxxxxxxx>, Wensong Zhang <wensong@xxxxxxxxxxxx>, Simon Horman <horms@xxxxxxxxxxxx>, Julian Anastasov <ja@xxxxxx>, Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>, James Morris <jmorris@xxxxxxxxx>, linux-scsi@xxxxxxxxxxxxxxx, linux-kernel@xxxxxxxxxxxxxxx, devel@xxxxxxxxxxxxxxxxxxxx, netdev@xxxxxxxxxxxxxxx, lvs-devel@xxxxxxxxxxxxxxx, netfilter-devel@xxxxxxxxxxxxxxx, coreteam@xxxxxxxxxxxxx, Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx>, Arnd Bergmann <arnd@xxxxxxxx>, Nishka Dasgupta <nishkadg.linux@xxxxxxxxx>
From: Arnd Bergmann <arnd@xxxxxxxx>
Date: Fri, 28 Jun 2019 14:37:48 +0200
An earlier patch I sent reduced the stack usage enough to get
below the warning limit, and I could show this was safe, but with
GCC_PLUGIN_STRUCTLEAK_BYREF_ALL, it gets worse again because large stack
variables in the same function no longer overlap:

drivers/staging/rtl8712/rtl871x_ioctl_linux.c: In function 
'translate_scan.isra.2':
drivers/staging/rtl8712/rtl871x_ioctl_linux.c:322:1: error: the frame size of 
1200 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]

Split out the largest two blocks in the affected function into two
separate functions and mark those noinline_for_stack.

Fixes: 8c5af16f7953 ("staging: rtl8712: reduce stack usage")
Fixes: 81a56f6dcd20 ("gcc-plugins: structleak: Generalize to all variable 
types")
Signed-off-by: Arnd Bergmann <arnd@xxxxxxxx>
---
 drivers/staging/rtl8712/rtl871x_ioctl_linux.c | 157 ++++++++++--------
 1 file changed, 88 insertions(+), 69 deletions(-)

diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c 
b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
index a224797cd993..fdc1df99d852 100644
--- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
+++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
@@ -124,10 +124,91 @@ static inline void handle_group_key(struct ieee_param 
*param,
        }
 }
 
-static noinline_for_stack char *translate_scan(struct _adapter *padapter,
-                                  struct iw_request_info *info,
-                                  struct wlan_network *pnetwork,
-                                  char *start, char *stop)
+static noinline_for_stack char *translate_scan_wpa(struct iw_request_info 
*info,
+                                                  struct wlan_network 
*pnetwork,
+                                                  struct iw_event *iwe,
+                                                  char *start, char *stop)
+{
+       /* parsing WPA/WPA2 IE */
+       u8 buf[MAX_WPA_IE_LEN];
+       u8 wpa_ie[255], rsn_ie[255];
+       u16 wpa_len = 0, rsn_len = 0;
+       int n, i;
+
+       r8712_get_sec_ie(pnetwork->network.IEs,
+                        pnetwork->network.IELength, rsn_ie, &rsn_len,
+                        wpa_ie, &wpa_len);
+       if (wpa_len > 0) {
+               memset(buf, 0, MAX_WPA_IE_LEN);
+               n = sprintf(buf, "wpa_ie=");
+               for (i = 0; i < wpa_len; i++) {
+                       n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
+                                               "%02x", wpa_ie[i]);
+                       if (n >= MAX_WPA_IE_LEN)
+                               break;
+               }
+               memset(iwe, 0, sizeof(*iwe));
+               iwe->cmd = IWEVCUSTOM;
+               iwe->u.data.length = (u16)strlen(buf);
+               start = iwe_stream_add_point(info, start, stop,
+                       iwe, buf);
+               memset(iwe, 0, sizeof(*iwe));
+               iwe->cmd = IWEVGENIE;
+               iwe->u.data.length = (u16)wpa_len;
+               start = iwe_stream_add_point(info, start, stop,
+                       iwe, wpa_ie);
+       }
+       if (rsn_len > 0) {
+               memset(buf, 0, MAX_WPA_IE_LEN);
+               n = sprintf(buf, "rsn_ie=");
+               for (i = 0; i < rsn_len; i++) {
+                       n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
+                                               "%02x", rsn_ie[i]);
+                       if (n >= MAX_WPA_IE_LEN)
+                               break;
+               }
+               memset(iwe, 0, sizeof(*iwe));
+               iwe->cmd = IWEVCUSTOM;
+               iwe->u.data.length = strlen(buf);
+               start = iwe_stream_add_point(info, start, stop,
+                       iwe, buf);
+               memset(iwe, 0, sizeof(*iwe));
+               iwe->cmd = IWEVGENIE;
+               iwe->u.data.length = rsn_len;
+               start = iwe_stream_add_point(info, start, stop, iwe,
+                       rsn_ie);
+       }
+
+       return start;
+}
+
+static noinline_for_stack char *translate_scan_wps(struct iw_request_info 
*info,
+                                                  struct wlan_network 
*pnetwork,
+                                                  struct iw_event *iwe,
+                                                  char *start, char *stop)
+{
+       /* parsing WPS IE */
+       u8 wps_ie[512];
+       uint wps_ielen;
+
+       if (r8712_get_wps_ie(pnetwork->network.IEs,
+           pnetwork->network.IELength,
+           wps_ie, &wps_ielen)) {
+               if (wps_ielen > 2) {
+                       iwe->cmd = IWEVGENIE;
+                       iwe->u.data.length = (u16)wps_ielen;
+                       start = iwe_stream_add_point(info, start, stop,
+                               iwe, wps_ie);
+               }
+       }
+
+       return start;
+}
+
+static char *translate_scan(struct _adapter *padapter,
+                           struct iw_request_info *info,
+                           struct wlan_network *pnetwork,
+                           char *start, char *stop)
 {
        struct iw_event iwe;
        struct ieee80211_ht_cap *pht_capie;
@@ -240,73 +321,11 @@ static noinline_for_stack char *translate_scan(struct 
_adapter *padapter,
        /* Check if we added any event */
        if ((current_val - start) > iwe_stream_lcp_len(info))
                start = current_val;
-       /* parsing WPA/WPA2 IE */
-       {
-               u8 buf[MAX_WPA_IE_LEN];
-               u8 wpa_ie[255], rsn_ie[255];
-               u16 wpa_len = 0, rsn_len = 0;
-               int n;
-
-               r8712_get_sec_ie(pnetwork->network.IEs,
-                                pnetwork->network.IELength, rsn_ie, &rsn_len,
-                                wpa_ie, &wpa_len);
-               if (wpa_len > 0) {
-                       memset(buf, 0, MAX_WPA_IE_LEN);
-                       n = sprintf(buf, "wpa_ie=");
-                       for (i = 0; i < wpa_len; i++) {
-                               n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
-                                                       "%02x", wpa_ie[i]);
-                               if (n >= MAX_WPA_IE_LEN)
-                                       break;
-                       }
-                       memset(&iwe, 0, sizeof(iwe));
-                       iwe.cmd = IWEVCUSTOM;
-                       iwe.u.data.length = (u16)strlen(buf);
-                       start = iwe_stream_add_point(info, start, stop,
-                               &iwe, buf);
-                       memset(&iwe, 0, sizeof(iwe));
-                       iwe.cmd = IWEVGENIE;
-                       iwe.u.data.length = (u16)wpa_len;
-                       start = iwe_stream_add_point(info, start, stop,
-                               &iwe, wpa_ie);
-               }
-               if (rsn_len > 0) {
-                       memset(buf, 0, MAX_WPA_IE_LEN);
-                       n = sprintf(buf, "rsn_ie=");
-                       for (i = 0; i < rsn_len; i++) {
-                               n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
-                                                       "%02x", rsn_ie[i]);
-                               if (n >= MAX_WPA_IE_LEN)
-                                       break;
-                       }
-                       memset(&iwe, 0, sizeof(iwe));
-                       iwe.cmd = IWEVCUSTOM;
-                       iwe.u.data.length = strlen(buf);
-                       start = iwe_stream_add_point(info, start, stop,
-                               &iwe, buf);
-                       memset(&iwe, 0, sizeof(iwe));
-                       iwe.cmd = IWEVGENIE;
-                       iwe.u.data.length = rsn_len;
-                       start = iwe_stream_add_point(info, start, stop, &iwe,
-                               rsn_ie);
-               }
-       }
 
-       { /* parsing WPS IE */
-               u8 wps_ie[512];
-               uint wps_ielen;
+       start = translate_scan_wpa(info, pnetwork, &iwe, start, stop);
+
+       start = translate_scan_wps(info, pnetwork, &iwe, start, stop);
 
-               if (r8712_get_wps_ie(pnetwork->network.IEs,
-                   pnetwork->network.IELength,
-                   wps_ie, &wps_ielen)) {
-                       if (wps_ielen > 2) {
-                               iwe.cmd = IWEVGENIE;
-                               iwe.u.data.length = (u16)wps_ielen;
-                               start = iwe_stream_add_point(info, start, stop,
-                                       &iwe, wps_ie);
-                       }
-               }
-       }
        /* Add quality statistics */
        iwe.cmd = IWEVQUAL;
        rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
-- 
2.20.0


<Prev in Thread] Current Thread [Next in Thread>