iwlwifi: range check to testmode direct reg access
authorAmit Beka <amit.beka@intel.com>
Wed, 25 Jan 2012 07:19:24 +0000 (09:19 +0200)
committerWey-Yi Guy <wey-yi.w.guy@intel.com>
Thu, 2 Feb 2012 22:38:42 +0000 (14:38 -0800)
Added a check on the direct register access.
Checks that the address is in the lower ragnge (0x0-0x2000),
which belongs to CSR, HBUS and FH registers.

Signed-off-by: Amit Beka <amit.beka@intel.com>
Signed-off-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com>
drivers/net/wireless/iwlwifi/iwl-testmode.c

index 7c17b9d5217960f24d0fe2087da025c6ab5d7fd0..df7ab332c833a38e41e5dc213d8a1221792b3cd2 100644 (file)
@@ -79,6 +79,7 @@
 #include "iwl-testmode.h"
 #include "iwl-trans.h"
 #include "iwl-bus.h"
+#include "iwl-fh.h"
 
 /* The TLVs used in the gnl message policy between the kernel module and
  * user space application. iwl_testmode_gnl_msg_policy is to be carried
@@ -288,7 +289,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
 static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
 {
        struct iwl_priv *priv = hw->priv;
-       u32 ofs, val32;
+       u32 ofs, val32, cmd;
        u8 val8;
        struct sk_buff *skb;
        int status = 0;
@@ -300,7 +301,20 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
        ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
        IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs);
 
-       switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
+       /* Allow access only to FH/CSR/HBUS in direct mode.
+       Since we don't have the upper bounds for the CSR and HBUS segments,
+       we will use only the upper bound of FH for sanity check. */
+       cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
+       if ((cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32 ||
+               cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 ||
+               cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8) &&
+               (ofs >= FH_MEM_UPPER_BOUND)) {
+               IWL_DEBUG_INFO(priv, "offset out of segment (0x0 - 0x%x)\n",
+                       FH_MEM_UPPER_BOUND);
+               return -EINVAL;
+       }
+
+       switch (cmd) {
        case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
                val32 = iwl_read_direct32(trans(priv), ofs);
                IWL_INFO(priv, "32bit value to read 0x%x\n", val32);