Commit 5dd8f535 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Greg Kroah-Hartman

staging: rtl8712: reduce stack usage, again

commit fbd6b250 upstream.

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: 8c5af16f ("staging: rtl8712: reduce stack usage")
Fixes: 81a56f6d ("gcc-plugins: structleak: Generalize to all variable types")
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 491a82be
...@@ -124,10 +124,91 @@ static inline void handle_group_key(struct ieee_param *param, ...@@ -124,10 +124,91 @@ static inline void handle_group_key(struct ieee_param *param,
} }
} }
static noinline_for_stack char *translate_scan(struct _adapter *padapter, static noinline_for_stack char *translate_scan_wpa(struct iw_request_info *info,
struct iw_request_info *info, struct wlan_network *pnetwork,
struct wlan_network *pnetwork, struct iw_event *iwe,
char *start, char *stop) 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 iw_event iwe;
struct ieee80211_ht_cap *pht_capie; struct ieee80211_ht_cap *pht_capie;
...@@ -240,73 +321,11 @@ static noinline_for_stack char *translate_scan(struct _adapter *padapter, ...@@ -240,73 +321,11 @@ static noinline_for_stack char *translate_scan(struct _adapter *padapter,
/* Check if we added any event */ /* Check if we added any event */
if ((current_val - start) > iwe_stream_lcp_len(info)) if ((current_val - start) > iwe_stream_lcp_len(info))
start = current_val; 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 */ start = translate_scan_wpa(info, pnetwork, &iwe, start, stop);
u8 wps_ie[512];
uint wps_ielen; 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 */ /* Add quality statistics */
iwe.cmd = IWEVQUAL; iwe.cmd = IWEVQUAL;
rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi); rssi = r8712_signal_scale_mapping(pnetwork->network.Rssi);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment