DroidSec: function iw_set_pno where sscanf return is not checked
Sscanf is called 10 times in this function, and return code is
checked for 4 of those calls. All must check return from all sscanf
to confirm that parameters were parsed correctly before subsequent
use
Change-Id: I83b56f05c7cc67284d802116dd054713ed2ab041
CRs-fixed: 554541
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index 820bfcf..1ca4353 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -6417,7 +6417,12 @@
-----------------------------------------------------------------------*/
ptr = (char*)(wrqu->data.pointer + nOffset);
- sscanf(ptr,"%hhu%n", &(pnoRequest.enable), &nOffset);
+ if (1 != sscanf(ptr,"%hhu%n", &(pnoRequest.enable), &nOffset))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "PNO enable input is not valid %s",ptr);
+ return VOS_STATUS_E_FAILURE;
+ }
if ( 0 == pnoRequest.enable )
{
@@ -6430,7 +6435,14 @@
}
ptr += nOffset;
- sscanf(ptr,"%hhu %n", &(pnoRequest.ucNetworksCount), &nOffset);
+
+ if (1 != sscanf(ptr,"%hhu %n", &(pnoRequest.ucNetworksCount), &nOffset))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "PNO count input not valid %s",ptr);
+ return VOS_STATUS_E_FAILURE;
+
+ }
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
"PNO enable %d networks count %d offset %d",
@@ -6454,8 +6466,15 @@
pnoRequest.aNetworks[i].ssId.length = 0;
- sscanf(ptr,"%hhu %n",
- &(pnoRequest.aNetworks[i].ssId.length), &nOffset);
+ ucParams = sscanf(ptr,"%hhu %n",
+ &(pnoRequest.aNetworks[i].ssId.length),&nOffset);
+
+ if (1 != ucParams)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "PNO ssid length input is not valid %s",ptr);
+ return VOS_STATUS_E_FAILURE;
+ }
if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
( pnoRequest.aNetworks[i].ssId.length > 32 ) )
@@ -6479,6 +6498,13 @@
&(pnoRequest.aNetworks[i].ucChannelCount),
&nOffset);
+ if ( 3 != ucParams )
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
+ "Incorrect cmd %s",ptr);
+ return VOS_STATUS_E_FAILURE;
+ }
+
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
"PNO len %d ssid 0x%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx"
"auth %d encry %d channel count %d offset %d",
@@ -6496,17 +6522,10 @@
pnoRequest.aNetworks[i].ucChannelCount,
nOffset );
- if ( 3 != ucParams )
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
- "Incorrect cmd");
- return VOS_STATUS_E_FAILURE;
- }
-
/*Advance to channel list*/
ptr += nOffset;
- if ( SIR_PNO_MAX_NETW_CHANNELS < pnoRequest.aNetworks[i].ucChannelCount )
+ if (SIR_PNO_MAX_NETW_CHANNELS < pnoRequest.aNetworks[i].ucChannelCount)
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
"Incorrect number of channels");
@@ -6517,15 +6536,26 @@
{
for ( j = 0; j < pnoRequest.aNetworks[i].ucChannelCount; j++)
{
- sscanf(ptr,"%hhu %n",
- &(pnoRequest.aNetworks[i].aChannels[j]), &nOffset);
- /*Advance to next channel number*/
- ptr += nOffset;
+ if (1 != sscanf(ptr,"%hhu %n",
+ &(pnoRequest.aNetworks[i].aChannels[j]),
+ &nOffset))
+ { VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "PNO network channel input is not valid %s",ptr);
+ return VOS_STATUS_E_FAILURE;
+ }
+ /*Advance to next channel number*/
+ ptr += nOffset;
}
}
- sscanf(ptr,"%lu %n",
- &(pnoRequest.aNetworks[i].bcastNetwType), &nOffset);
+ if (1 != sscanf(ptr,"%lu %n",
+ &(pnoRequest.aNetworks[i].bcastNetwType),
+ &nOffset))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "PNO broadcast network type input is not valid %s",ptr);
+ return VOS_STATUS_E_FAILURE;
+ }
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
"PNO bcastNetwType %d offset %d",
@@ -6535,8 +6565,14 @@
/*Advance to rssi Threshold*/
ptr += nOffset;
- sscanf(ptr,"%hhu %n",
- &(pnoRequest.aNetworks[i].rssiThreshold), &nOffset);
+ if (1 != sscanf(ptr,"%hhu %n",
+ &(pnoRequest.aNetworks[i].rssiThreshold),
+ &nOffset))
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "PNO rssi threshold input is not valid %s",ptr);
+ return VOS_STATUS_E_FAILURE;
+ }
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
"PNO rssi %d offset %d",
@@ -6547,7 +6583,8 @@
}/*For ucNetworkCount*/
ucParams = sscanf(ptr,"%hhu %n",
- &(pnoRequest.scanTimers.ucScanTimersCount), &nOffset);
+ &(pnoRequest.scanTimers.ucScanTimersCount),
+ &nOffset);
/*Read the scan timers*/
if (( 1 == ucParams ) && ( pnoRequest.scanTimers.ucScanTimersCount > 0 ))
@@ -6573,19 +6610,19 @@
&( pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat),
&nOffset);
+ if (2 != ucParams)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "Incorrect cmd - diff params then expected %d", ucParams);
+ return VOS_STATUS_E_FAILURE;
+ }
+
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
"PNO Timer value %d Timer repeat %d offset %d",
pnoRequest.scanTimers.aTimerValues[i].uTimerValue,
pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat,
nOffset );
- if ( 2 != ucParams )
- {
- VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- "Incorrect cmd - diff params then expected %d", ucParams);
- return VOS_STATUS_E_FAILURE;
- }
-
ptr += nOffset;
}
@@ -6602,8 +6639,7 @@
pnoRequest.scanTimers.aTimerValues[0].uTimerRepeat = 0;
}
- ucParams = sscanf(ptr,"%hhu %n",
- &(ucMode), &nOffset);
+ ucParams = sscanf(ptr,"%hhu %n",&(ucMode), &nOffset);
pnoRequest.modePNO = ucMode;
/*for LA we just expose suspend option*/