iwlwifi: add range checking in tm sram read command
authorKenny Hsu <kenny.hsu@intel.com>
Fri, 2 Dec 2011 16:48:27 +0000 (08:48 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 6 Dec 2011 21:06:54 +0000 (16:06 -0500)
The size of sram may alter according to ucode type.
Retrieve the maximum sram size by current ucode
type for range checking to prevent wrong data access.

Signed-off-by: Kenny Hsu <kenny.hsu@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlwifi/iwl-sv-open.c

index 593f42d9fb0ae2b34ec23c4a2856a85866862c1b..a8d0ef649a7c6b989f95fcd201f61965aa49c8f7 100644 (file)
@@ -680,7 +680,7 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
 static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb)
 {
        struct iwl_priv *priv = hw->priv;
-       u32 base, ofs, size;
+       u32 base, ofs, size, maxsize;
 
        if (priv->testmode_sram.sram_readed)
                return -EBUSY;
@@ -695,6 +695,27 @@ static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb)
                return -ENOMSG;
        }
        size = nla_get_u32(tb[IWL_TM_ATTR_SRAM_SIZE]);
+       switch (priv->ucode_type) {
+       case IWL_UCODE_REGULAR:
+               maxsize = trans(priv)->ucode_rt.data.len;
+               break;
+       case IWL_UCODE_INIT:
+               maxsize = trans(priv)->ucode_init.data.len;
+               break;
+       case IWL_UCODE_WOWLAN:
+               maxsize = trans(priv)->ucode_wowlan.data.len;
+               break;
+       case IWL_UCODE_NONE:
+               IWL_DEBUG_INFO(priv, "Error, uCode does not been loaded\n");
+               return -ENOSYS;
+       default:
+               IWL_DEBUG_INFO(priv, "Error, unsupported uCode type\n");
+               return -ENOSYS;
+       }
+       if ((ofs + size) > maxsize) {
+               IWL_DEBUG_INFO(priv, "Invalid offset/size: out of range\n");
+               return -EINVAL;
+       }
        priv->testmode_sram.buff_size = (size / 4) * 4;
        priv->testmode_sram.buff_addr =
                kmalloc(priv->testmode_sram.buff_size, GFP_KERNEL);