aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-07-14 12:34:50 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2010-07-23 11:42:04 -0400
commit704da534af1e366214f790b381fed73ba6c5d37b (patch)
tree236f4d47ada3449688f7de3013fafdd68c6a92a1 /drivers/net/wireless
parent6a822d060c439bb700f2369767105f49135b94f8 (diff)
iwlagn: fix firmware loading TLV error path
gcc complains about the firmware loading: iwl-agn.c: In function ‘iwlagn_load_firmware’: iwl-agn.c:1860: warning: ‘tlv_len’ may be used uninitialized in this function iwl-agn.c:1861: warning: ‘tlv_type’ may be used uninitialized in this function iwl-agn.c:1862: warning: ‘tlv_data’ may be used uninitialized in this function This is almost correct but we do do break out of the TLV parsing loop when setting ret. However, the code is hard to follow, and clearly even the compiler is having issues with it too. Additionally, however, the current code is wrong. If there is a TLV length check error, the code will report invalid TLV after parsing: ... because "len" will still be non-zero as we broke out of the loop. So to remove the warning and fix that issue, make the code easier to read by doing length checking with an error label. As a result, we can completely remove the "ret" variable. Also, while at it, remove the "fixed_tlv_size" variable since each TLV type has its own specified length, it just happens that we have only variable length, flags (0 length) and u32 TLVs right now. It should still be checked with more explicit length checks to make it easier to understand. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c79
1 files changed, 35 insertions, 44 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index db86f70d1a3f..573a81b494ea 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1828,7 +1828,6 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1828 u32 tlv_len; 1828 u32 tlv_len;
1829 enum iwl_ucode_tlv_type tlv_type; 1829 enum iwl_ucode_tlv_type tlv_type;
1830 const u8 *tlv_data; 1830 const u8 *tlv_data;
1831 int ret = 0;
1832 1831
1833 if (len < sizeof(*ucode)) { 1832 if (len < sizeof(*ucode)) {
1834 IWL_ERR(priv, "uCode has invalid length: %zd\n", len); 1833 IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
@@ -1864,9 +1863,8 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1864 1863
1865 len -= sizeof(*ucode); 1864 len -= sizeof(*ucode);
1866 1865
1867 while (len >= sizeof(*tlv) && !ret) { 1866 while (len >= sizeof(*tlv)) {
1868 u16 tlv_alt; 1867 u16 tlv_alt;
1869 u32 fixed_tlv_size = 4;
1870 1868
1871 len -= sizeof(*tlv); 1869 len -= sizeof(*tlv);
1872 tlv = (void *)data; 1870 tlv = (void *)data;
@@ -1914,65 +1912,56 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1914 pieces->boot_size = tlv_len; 1912 pieces->boot_size = tlv_len;
1915 break; 1913 break;
1916 case IWL_UCODE_TLV_PROBE_MAX_LEN: 1914 case IWL_UCODE_TLV_PROBE_MAX_LEN:
1917 if (tlv_len != fixed_tlv_size) 1915 if (tlv_len != sizeof(u32))
1918 ret = -EINVAL; 1916 goto invalid_tlv_len;
1919 else 1917 capa->max_probe_length =
1920 capa->max_probe_length =
1921 le32_to_cpup((__le32 *)tlv_data); 1918 le32_to_cpup((__le32 *)tlv_data);
1922 break; 1919 break;
1923 case IWL_UCODE_TLV_INIT_EVTLOG_PTR: 1920 case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
1924 if (tlv_len != fixed_tlv_size) 1921 if (tlv_len != sizeof(u32))
1925 ret = -EINVAL; 1922 goto invalid_tlv_len;
1926 else 1923 pieces->init_evtlog_ptr =
1927 pieces->init_evtlog_ptr =
1928 le32_to_cpup((__le32 *)tlv_data); 1924 le32_to_cpup((__le32 *)tlv_data);
1929 break; 1925 break;
1930 case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: 1926 case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
1931 if (tlv_len != fixed_tlv_size) 1927 if (tlv_len != sizeof(u32))
1932 ret = -EINVAL; 1928 goto invalid_tlv_len;
1933 else 1929 pieces->init_evtlog_size =
1934 pieces->init_evtlog_size =
1935 le32_to_cpup((__le32 *)tlv_data); 1930 le32_to_cpup((__le32 *)tlv_data);
1936 break; 1931 break;
1937 case IWL_UCODE_TLV_INIT_ERRLOG_PTR: 1932 case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
1938 if (tlv_len != fixed_tlv_size) 1933 if (tlv_len != sizeof(u32))
1939 ret = -EINVAL; 1934 goto invalid_tlv_len;
1940 else 1935 pieces->init_errlog_ptr =
1941 pieces->init_errlog_ptr =
1942 le32_to_cpup((__le32 *)tlv_data); 1936 le32_to_cpup((__le32 *)tlv_data);
1943 break; 1937 break;
1944 case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: 1938 case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
1945 if (tlv_len != fixed_tlv_size) 1939 if (tlv_len != sizeof(u32))
1946 ret = -EINVAL; 1940 goto invalid_tlv_len;
1947 else 1941 pieces->inst_evtlog_ptr =
1948 pieces->inst_evtlog_ptr =
1949 le32_to_cpup((__le32 *)tlv_data); 1942 le32_to_cpup((__le32 *)tlv_data);
1950 break; 1943 break;
1951 case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: 1944 case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
1952 if (tlv_len != fixed_tlv_size) 1945 if (tlv_len != sizeof(u32))
1953 ret = -EINVAL; 1946 goto invalid_tlv_len;
1954 else 1947 pieces->inst_evtlog_size =
1955 pieces->inst_evtlog_size =
1956 le32_to_cpup((__le32 *)tlv_data); 1948 le32_to_cpup((__le32 *)tlv_data);
1957 break; 1949 break;
1958 case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: 1950 case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
1959 if (tlv_len != fixed_tlv_size) 1951 if (tlv_len != sizeof(u32))
1960 ret = -EINVAL; 1952 goto invalid_tlv_len;
1961 else 1953 pieces->inst_errlog_ptr =
1962 pieces->inst_errlog_ptr =
1963 le32_to_cpup((__le32 *)tlv_data); 1954 le32_to_cpup((__le32 *)tlv_data);
1964 break; 1955 break;
1965 case IWL_UCODE_TLV_ENHANCE_SENS_TBL: 1956 case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
1966 if (tlv_len) 1957 if (tlv_len)
1967 ret = -EINVAL; 1958 goto invalid_tlv_len;
1968 else 1959 priv->enhance_sensitivity_table = true;
1969 priv->enhance_sensitivity_table = true;
1970 break; 1960 break;
1971 case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: 1961 case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE:
1972 if (tlv_len != fixed_tlv_size) 1962 if (tlv_len != sizeof(u32))
1973 ret = -EINVAL; 1963 goto invalid_tlv_len;
1974 else 1964 capa->standard_phy_calibration_size =
1975 capa->standard_phy_calibration_size =
1976 le32_to_cpup((__le32 *)tlv_data); 1965 le32_to_cpup((__le32 *)tlv_data);
1977 break; 1966 break;
1978 default: 1967 default:
@@ -1984,14 +1973,16 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
1984 if (len) { 1973 if (len) {
1985 IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); 1974 IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
1986 iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); 1975 iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
1987 ret = -EINVAL; 1976 return -EINVAL;
1988 } else if (ret) {
1989 IWL_ERR(priv, "TLV %d has invalid size: %u\n",
1990 tlv_type, tlv_len);
1991 iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)tlv_data, tlv_len);
1992 } 1977 }
1993 1978
1994 return ret; 1979 return 0;
1980
1981 invalid_tlv_len:
1982 IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
1983 iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len);
1984
1985 return -EINVAL;
1995} 1986}
1996 1987
1997/** 1988/**