mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
95 lines
3.2 KiB
Diff
95 lines
3.2 KiB
Diff
|
From 7d0e40d328fa092c36b9585516ed29fc6041be55 Mon Sep 17 00:00:00 2001
|
||
|
From: Jeff Johnson <jjohnson@codeaurora.org>
|
||
|
Date: Tue, 6 Jun 2017 12:53:28 -0700
|
||
|
Subject: 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
|
||
|
---
|
||
|
core/hdd/src/wlan_hdd_disa.c | 24 +++++++++++++++++++-----
|
||
|
1 file changed, 19 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/core/hdd/src/wlan_hdd_disa.c b/core/hdd/src/wlan_hdd_disa.c
|
||
|
index c2e99d1..39e6bd1 100644
|
||
|
--- a/core/hdd/src/wlan_hdd_disa.c
|
||
|
+++ b/core/hdd/src/wlan_hdd_disa.c
|
||
|
@@ -159,6 +159,16 @@ nla_put_failure:
|
||
|
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
|
||
|
* and fills encrypt/decrypt parameters
|
||
|
@@ -181,7 +191,7 @@ static int hdd_fill_encrypt_decrypt_params(struct encrypt_decrypt_req_params
|
||
|
uint8_t fc[2];
|
||
|
|
||
|
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");
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
@@ -243,8 +253,8 @@ static int hdd_fill_encrypt_decrypt_params(struct encrypt_decrypt_req_params
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_PN]);
|
||
|
- if (!len) {
|
||
|
- hdd_err("Invalid PN length");
|
||
|
+ if (!len || len > sizeof(encrypt_decrypt_params->pn)) {
|
||
|
+ hdd_err("Invalid PN length %u", len);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
@@ -260,8 +270,8 @@ static int hdd_fill_encrypt_decrypt_params(struct encrypt_decrypt_req_params
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_ENCRYPTION_TEST_DATA]);
|
||
|
- if (!len) {
|
||
|
- hdd_err("Invalid header and payload length");
|
||
|
+ if (len < MIN_MAC_HEADER_LEN) {
|
||
|
+ hdd_err("Invalid header and payload length %u", len);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
|
||
|
@@ -298,6 +308,10 @@ static int hdd_fill_encrypt_decrypt_params(struct encrypt_decrypt_req_params
|
||
|
|
||
|
hdd_notice("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,
|
||
|
tmp, mac_hdr_len);
|
||
|
|
||
|
--
|
||
|
cgit v1.1
|
||
|
|