qcacld-3.0: Fix buffer overread & overflow in DISA handler
Currently in hdd_fill_encrypt_decrypt_params() there are multiple issues with the incoming cfg80211 vendor command handling: 1) A policy is not supplied when invoking nla_parse() which prevents basic sanity of the incoming attribute stream. 2) The length of attribute QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN is not properly validated. 3) The length of attribute QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA is not properly validated. To address these issues: 1) Create an appropriate nla_policy and specify this policy when invoking nla_parse(). 2) Validate the length of QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN to prevent potential buffer overflow. 3) Validate the length of QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA to prevent potential buffer overread. Change-Id: Ibb86897f249010c94c4098b283aad7a7f95ab9a2 CRs-Fixed: 2054760
This commit is contained in:
@@ -146,6 +146,16 @@ nla_put_failure:
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct nla_policy
|
||||||
|
encrypt_decrypt_policy[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX + 1] = {
|
||||||
|
[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_NEEDS_DECRYPTION] = {
|
||||||
|
.type = NLA_FLAG},
|
||||||
|
[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_KEYID] = {
|
||||||
|
.type = NLA_U8},
|
||||||
|
[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_CIPHER] = {
|
||||||
|
.type = NLA_U32},
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hdd_fill_encrypt_decrypt_params () - parses data from user space
|
* hdd_fill_encrypt_decrypt_params () - parses data from user space
|
||||||
* and fills encrypt/decrypt parameters
|
* and fills encrypt/decrypt parameters
|
||||||
@@ -168,7 +178,7 @@ static int hdd_fill_encrypt_decrypt_params(struct encrypt_decrypt_req_params
|
|||||||
uint8_t fc[2];
|
uint8_t fc[2];
|
||||||
|
|
||||||
if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX,
|
if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_MAX,
|
||||||
data, data_len, NULL)) {
|
data, data_len, encrypt_decrypt_policy)) {
|
||||||
hdd_err("Invalid ATTR");
|
hdd_err("Invalid ATTR");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -230,8 +240,8 @@ static int hdd_fill_encrypt_decrypt_params(struct encrypt_decrypt_req_params
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN]);
|
len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN]);
|
||||||
if (!len) {
|
if (!len || len > sizeof(encrypt_decrypt_params->pn)) {
|
||||||
hdd_err("Invalid PN length");
|
hdd_err("Invalid PN length %u", len);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,8 +257,8 @@ static int hdd_fill_encrypt_decrypt_params(struct encrypt_decrypt_req_params
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA]);
|
len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA]);
|
||||||
if (!len) {
|
if (len < MIN_MAC_HEADER_LEN) {
|
||||||
hdd_err("Invalid header and payload length");
|
hdd_err("Invalid header and payload length %u", len);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,6 +295,10 @@ static int hdd_fill_encrypt_decrypt_params(struct encrypt_decrypt_req_params
|
|||||||
|
|
||||||
hdd_debug("mac_hdr_len: %d", mac_hdr_len);
|
hdd_debug("mac_hdr_len: %d", mac_hdr_len);
|
||||||
|
|
||||||
|
if (len < mac_hdr_len) {
|
||||||
|
hdd_err("Invalid header and payload length %u", len);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
qdf_mem_copy(encrypt_decrypt_params->mac_header,
|
qdf_mem_copy(encrypt_decrypt_params->mac_header,
|
||||||
tmp, mac_hdr_len);
|
tmp, mac_hdr_len);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user