Merge branch 'android-msm-bullhead-3.10-security-next' into android-msm-bullhead-3.10
March 2018.1
Change-Id: Ice243e35cad9f32e9ab30bc007f00440bae25aff
diff --git a/afcebb8.diff b/afcebb8.diff
new file mode 100644
index 0000000..deade5b
--- /dev/null
+++ b/afcebb8.diff
@@ -0,0 +1,38 @@
+From afcebb82f391776dc332a268d6a582f8de0b7a23 Mon Sep 17 00:00:00 2001
+From: Srinivas Girigowda <sgirigow@codeaurora.org>
+Date: Wed, 26 Jul 2017 12:17:20 +0530
+Subject: [PATCH] qcacld-2.0: Fix incorrect processing of encrypted auth frame
+
+qcacld-3.0 to qcacld-2.0 propagation.
+
+Fix incorrect processing of encrypted auth frame by allocating
+appropriate local buffer and using correct type for frame length.
+
+Change-Id: I0d17656230c4a032c6a190835343e5da737978eb
+CRs-Fixed: 2082544
+Bug: 67030205
+Signed-off-by: Srinivas Girigowda <sgirigow@codeaurora.org>
+---
+
+diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c
+index 049c86a..909a300 100644
+--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c
++++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.c
+@@ -734,7 +734,7 @@
+ {
+ tANI_U8 i = ctx.i;
+ tANI_U8 j = ctx.j;
+- tANI_U8 len = (tANI_U8) frameLen;
++ tANI_U16 len = frameLen;
+
+ while (len-- > 0)
+ {
+@@ -816,7 +816,7 @@
+ // Compute CRC-32 and place them in last 4 bytes of encrypted body
+ limComputeCrc32(icv,
+ (tANI_U8 *) pPlainBody,
+- (tANI_U8) (frameLen - SIR_MAC_WEP_ICV_LENGTH));
++ (frameLen - SIR_MAC_WEP_ICV_LENGTH));
+
+ // Compare RX_ICV with computed ICV
+ for (i = 0; i < SIR_MAC_WEP_ICV_LENGTH; i++)
diff --git a/afcebb8.diff.zip b/afcebb8.diff.zip
new file mode 100644
index 0000000..16b7b66
--- /dev/null
+++ b/afcebb8.diff.zip
Binary files differ
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
index 6916507..5160c7b 100644
--- a/drivers/char/diag/diag_debugfs.c
+++ b/drivers/char/diag/diag_debugfs.c
@@ -36,7 +36,7 @@
static int diag_dbgfs_finished;
static int diag_dbgfs_dci_data_index;
static int diag_dbgfs_dci_finished;
-
+static struct mutex diag_dci_dbgfs_mutex;
static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
size_t count, loff_t *ppos)
{
@@ -357,6 +357,7 @@
buf_size = ksize(buf);
bytes_remaining = buf_size;
+ mutex_lock(&diag_dci_dbgfs_mutex);
if (diag_dbgfs_dci_data_index == 0) {
bytes_written =
scnprintf(buf, buf_size,
@@ -412,8 +413,8 @@
}
temp_data++;
}
-
diag_dbgfs_dci_data_index = (i >= DIAG_DCI_DEBUG_CNT) ? 0 : i + 1;
+ mutex_unlock(&diag_dci_dbgfs_mutex);
bytes_written = simple_read_from_buffer(ubuf, count, ppos, buf,
bytes_in_buf);
kfree(buf);
@@ -1084,6 +1085,7 @@
pr_warn("diag: could not allocate memory for dci debug info\n");
mutex_init(&dci_stat_mutex);
+ mutex_init(&diag_dci_dbgfs_mutex);
return 0;
err:
kfree(dci_traffic);
@@ -1100,6 +1102,7 @@
kfree(dci_traffic);
mutex_destroy(&dci_stat_mutex);
+ mutex_destroy(&diag_dci_dbgfs_mutex);
}
#else
int diag_debugfs_init(void) { return 0; }
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index c9461d6..be581c2 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1051,14 +1051,18 @@
{
int i;
+ mutex_lock(&driver->diagchar_mutex);
for (i = 0; i < driver->num_clients; i++)
if (driver->client_map[i].pid == current->tgid)
break;
- if (i == driver->num_clients)
+ if (i == driver->num_clients) {
+ mutex_unlock(&driver->diagchar_mutex);
return -EINVAL;
+ }
driver->data_ready[i] |= DEINIT_TYPE;
+ mutex_unlock(&driver->diagchar_mutex);
wake_up_interruptible(&driver->wait_q);
return 1;
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index ada164e..60d77af 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -1016,6 +1016,8 @@
unsigned int rsize = 0;
char *rdesc;
int ret, n;
+ int num_descriptors;
+ size_t offset = offsetof(struct hid_descriptor, desc);
quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
@@ -1038,10 +1040,18 @@
return -ENODEV;
}
+ if (hdesc->bLength < sizeof(struct hid_descriptor)) {
+ dbg_hid("hid descriptor is too short\n");
+ return -EINVAL;
+ }
+
hid->version = le16_to_cpu(hdesc->bcdHID);
hid->country = hdesc->bCountryCode;
- for (n = 0; n < hdesc->bNumDescriptors; n++)
+ num_descriptors = min_t(int, hdesc->bNumDescriptors,
+ (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
+
+ for (n = 0; n < num_descriptors; n++)
if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
index 0390e0e..40d731b 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
@@ -1114,6 +1114,9 @@
break;
}
break;
+ case VIDIOC_MSM_FLASH_CFG:
+ pr_err("invalid cmd 0x%x received\n", cmd);
+ return -EINVAL;
default:
return msm_flash_subdev_ioctl(sd, cmd, arg);
}
diff --git a/drivers/platform/msm/ipa/ipa_flt.c b/drivers/platform/msm/ipa/ipa_flt.c
index 72342c2..54328b7 100644
--- a/drivers/platform/msm/ipa/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_flt.c
@@ -1017,7 +1017,7 @@
goto error;
}
- if (rt_tbl->cookie != IPA_COOKIE) {
+ if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}
@@ -1038,7 +1038,7 @@
}
INIT_LIST_HEAD(&entry->link);
entry->rule = *rule;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_FLT_COOKIE;
entry->rt_tbl = rt_tbl;
entry->tbl = tbl;
if (add_rear) {
@@ -1057,13 +1057,19 @@
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
*rule_hdl = id;
entry->id = id;
IPADBG("add flt rule rule_cnt=%d\n", tbl->rule_cnt);
return 0;
-
+ipa_insert_failed:
+ tbl->rule_cnt--;
+ if (entry->rt_tbl)
+ entry->rt_tbl->ref_cnt--;
+ list_del(&entry->link);
+ kmem_cache_free(ipa_ctx->flt_rule_cache, entry);
error:
return -EPERM;
}
@@ -1079,7 +1085,7 @@
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -1111,7 +1117,7 @@
goto error;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
goto error;
}
@@ -1132,7 +1138,7 @@
goto error;
}
- if (rt_tbl->cookie != IPA_COOKIE) {
+ if (rt_tbl->cookie != IPA_RT_TBL_COOKIE) {
IPAERR("RT table cookie is invalid\n");
goto error;
}
diff --git a/drivers/platform/msm/ipa/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_hdr.c
index 52be0fb..92974c7 100644
--- a/drivers/platform/msm/ipa/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_hdr.c
@@ -469,7 +469,7 @@
{
struct ipa_hdr_entry *hdr_entry;
struct ipa_hdr_proc_ctx_entry *entry;
- struct ipa_hdr_proc_ctx_offset_entry *offset;
+ struct ipa_hdr_proc_ctx_offset_entry *offset = NULL;
u32 bin;
struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
int id;
@@ -484,7 +484,7 @@
}
hdr_entry = ipa_id_find(proc_ctx->hdr_hdl);
- if (!hdr_entry || (hdr_entry->cookie != IPA_COOKIE)) {
+ if (!hdr_entry || (hdr_entry->cookie != IPA_HDR_COOKIE)) {
IPAERR("hdr_hdl is invalid\n");
return -EINVAL;
}
@@ -501,7 +501,7 @@
entry->hdr = hdr_entry;
if (add_ref_hdr)
hdr_entry->ref_cnt++;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_PROC_HDR_COOKIE;
needed_len = (proc_ctx->type == IPA_HDR_PROC_NONE) ?
sizeof(struct ipa_hdr_proc_ctx_add_hdr_seq) :
@@ -553,6 +553,7 @@
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
proc_ctx->proc_ctx_hdl = id;
@@ -560,6 +561,13 @@
return 0;
+ipa_insert_failed:
+ if (offset)
+ list_move(&offset->link,
+ &htbl->head_free_offset_list[offset->bin]);
+ entry->offset_entry = NULL;
+ list_del(&entry->link);
+ htbl->proc_ctx_cnt--;
bad_len:
if (add_ref_hdr)
hdr_entry->ref_cnt--;
@@ -572,7 +580,7 @@
static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
{
struct ipa_hdr_entry *entry;
- struct ipa_hdr_offset_entry *offset;
+ struct ipa_hdr_offset_entry *offset = NULL;
u32 bin;
struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl;
int id;
@@ -603,7 +611,7 @@
entry->type = hdr->type;
entry->is_eth2_ofst_valid = hdr->is_eth2_ofst_valid;
entry->eth2_ofst = hdr->eth2_ofst;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_HDR_COOKIE;
if (hdr->hdr_len <= ipa_hdr_bin_sz[IPA_HDR_BIN0])
bin = IPA_HDR_BIN0;
@@ -685,6 +693,7 @@
if (id < 0) {
IPAERR("failed to alloc id\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
hdr->hdr_hdl = id;
@@ -709,10 +718,19 @@
entry->ref_cnt--;
hdr->hdr_hdl = 0;
ipa_id_remove(id);
+ipa_insert_failed:
+ if (entry->is_hdr_proc_ctx) {
+ dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
+ entry->hdr_len, DMA_TO_DEVICE);
+ } else {
+ if (offset)
+ list_move(&offset->link,
+ &htbl->head_free_offset_list[offset->bin]);
+ entry->offset_entry = NULL;
+ }
+
htbl->hdr_cnt--;
list_del(&entry->link);
- dma_unmap_single(ipa_ctx->pdev, entry->phys_base,
- entry->hdr_len, DMA_TO_DEVICE);
bad_hdr_len:
entry->cookie = 0;
kmem_cache_free(ipa_ctx->hdr_cache, entry);
@@ -727,7 +745,7 @@
struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
entry = ipa_id_find(proc_ctx_hdl);
- if (!entry || (entry->cookie != IPA_COOKIE)) {
+ if (!entry || (entry->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("bad parm\n");
return -EINVAL;
}
@@ -778,7 +796,7 @@
return -EINVAL;
}
- if (!entry || (entry->cookie != IPA_COOKIE)) {
+ if (!entry || (entry->cookie != IPA_HDR_COOKIE)) {
IPAERR("bad parm\n");
return -EINVAL;
}
@@ -1314,7 +1332,7 @@
goto bail;
}
- if (entry == NULL || entry->cookie != IPA_COOKIE) {
+ if (entry == NULL || entry->cookie != IPA_HDR_COOKIE) {
IPAERR("bad params\n");
result = -EINVAL;
goto bail;
diff --git a/drivers/platform/msm/ipa/ipa_i.h b/drivers/platform/msm/ipa/ipa_i.h
index 3f40633..432be55 100644
--- a/drivers/platform/msm/ipa/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_i.h
@@ -31,6 +31,12 @@
#define DRV_NAME "ipa"
#define NAT_DEV_NAME "ipaNatTable"
#define IPA_COOKIE 0x57831603
+#define IPA_RT_RULE_COOKIE 0x57831604
+#define IPA_RT_TBL_COOKIE 0x57831605
+#define IPA_FLT_COOKIE 0x57831606
+#define IPA_HDR_COOKIE 0x57831607
+#define IPA_PROC_HDR_COOKIE 0x57831608
+
#define MTU_BYTE 1500
#define IPA_NUM_PIPES 0x14
@@ -167,8 +173,8 @@
*/
struct ipa_flt_entry {
struct list_head link;
- struct ipa_flt_rule rule;
u32 cookie;
+ struct ipa_flt_rule rule;
struct ipa_flt_tbl *tbl;
struct ipa_rt_tbl *rt_tbl;
u32 hw_len;
@@ -193,13 +199,13 @@
*/
struct ipa_rt_tbl {
struct list_head link;
+ u32 cookie;
struct list_head head_rt_rule_list;
char name[IPA_RESOURCE_NAME_MAX];
u32 idx;
u32 rule_cnt;
u32 ref_cnt;
struct ipa_rt_tbl_set *set;
- u32 cookie;
bool in_sys;
u32 sz;
struct ipa_mem_buffer curr_mem;
@@ -230,6 +236,7 @@
*/
struct ipa_hdr_entry {
struct list_head link;
+ u32 cookie;
u8 hdr[IPA_HDR_MAX_SIZE];
u32 hdr_len;
char name[IPA_RESOURCE_NAME_MAX];
@@ -239,7 +246,6 @@
dma_addr_t phys_base;
struct ipa_hdr_proc_ctx_entry *proc_ctx;
struct ipa_hdr_offset_entry *offset_entry;
- u32 cookie;
u32 ref_cnt;
int id;
u8 is_eth2_ofst_valid;
@@ -324,10 +330,10 @@
*/
struct ipa_hdr_proc_ctx_entry {
struct list_head link;
+ u32 cookie;
enum ipa_hdr_proc_type type;
struct ipa_hdr_proc_ctx_offset_entry *offset_entry;
struct ipa_hdr_entry *hdr;
- u32 cookie;
u32 ref_cnt;
int id;
bool user_deleted;
@@ -383,8 +389,8 @@
*/
struct ipa_rt_entry {
struct list_head link;
- struct ipa_rt_rule rule;
u32 cookie;
+ struct ipa_rt_rule rule;
struct ipa_rt_tbl *tbl;
struct ipa_hdr_entry *hdr;
struct ipa_hdr_proc_ctx_entry *proc_ctx;
diff --git a/drivers/platform/msm/ipa/ipa_rt.c b/drivers/platform/msm/ipa/ipa_rt.c
index 81c6331..ba28ba7 100644
--- a/drivers/platform/msm/ipa/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_rt.c
@@ -839,7 +839,7 @@
INIT_LIST_HEAD(&entry->link);
strlcpy(entry->name, name, IPA_RESOURCE_NAME_MAX);
entry->set = set;
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_RT_TBL_COOKIE;
entry->in_sys = (ip == IPA_IP_v4) ?
!ipa_ctx->ip4_rt_tbl_lcl : !ipa_ctx->ip6_rt_tbl_lcl;
set->tbl_cnt++;
@@ -852,12 +852,16 @@
if (id < 0) {
IPAERR("failed to add to tree\n");
WARN_ON(1);
+ goto ipa_insert_failed;
}
entry->id = id;
}
return entry;
+ipa_insert_failed:
+ set->tbl_cnt--;
+ list_del(&entry->link);
fail_rt_idx_alloc:
entry->cookie = 0;
kmem_cache_free(ipa_ctx->rt_tbl_cache, entry);
@@ -870,7 +874,7 @@
enum ipa_ip_type ip = IPA_IP_MAX;
u32 id;
- if (entry == NULL || (entry->cookie != IPA_COOKIE)) {
+ if (entry == NULL || (entry->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("bad parms\n");
return -EINVAL;
}
@@ -884,8 +888,10 @@
ip = IPA_IP_v4;
else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
- else
+ else {
WARN_ON(1);
+ return -EPERM;
+ }
if (!entry->in_sys) {
list_del(&entry->link);
@@ -924,13 +930,14 @@
if (rule->hdr_hdl) {
hdr = ipa_id_find(rule->hdr_hdl);
- if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
+ if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
goto error;
}
} else if (rule->hdr_proc_ctx_hdl) {
proc_ctx = ipa_id_find(rule->hdr_proc_ctx_hdl);
- if ((proc_ctx == NULL) || (proc_ctx->cookie != IPA_COOKIE)) {
+ if ((proc_ctx == NULL) ||
+ (proc_ctx->cookie != IPA_PROC_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid proc ctx\n");
goto error;
}
@@ -938,7 +945,7 @@
tbl = __ipa_add_rt_tbl(ip, name);
- if (tbl == NULL || (tbl->cookie != IPA_COOKIE)) {
+ if (tbl == NULL || (tbl->cookie != IPA_RT_TBL_COOKIE)) {
IPAERR("bad params\n");
goto error;
}
@@ -959,7 +966,7 @@
goto error;
}
INIT_LIST_HEAD(&entry->link);
- entry->cookie = IPA_COOKIE;
+ entry->cookie = IPA_RT_RULE_COOKIE;
entry->rule = *rule;
entry->tbl = tbl;
entry->hdr = hdr;
@@ -1049,7 +1056,7 @@
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -1288,7 +1295,7 @@
}
mutex_lock(&ipa_ctx->lock);
entry = __ipa_find_rt_tbl(lookup->ip, lookup->name);
- if (entry && entry->cookie == IPA_COOKIE) {
+ if (entry && entry->cookie == IPA_RT_TBL_COOKIE) {
if (entry->ref_cnt == ((u32)~0U)) {
IPAERR("fail: ref count crossed limit\n");
goto ret;
@@ -1332,7 +1339,7 @@
goto ret;
}
- if ((entry->cookie != IPA_COOKIE) || entry->ref_cnt == 0) {
+ if ((entry->cookie != IPA_RT_TBL_COOKIE) || entry->ref_cnt == 0) {
IPAERR("bad parms\n");
result = -EINVAL;
goto ret;
@@ -1342,8 +1349,11 @@
ip = IPA_IP_v4;
else if (entry->set == &ipa_ctx->rt_tbl_set[IPA_IP_v6])
ip = IPA_IP_v6;
- else
+ else {
WARN_ON(1);
+ result = -EINVAL;
+ goto ret;
+ }
entry->ref_cnt--;
if (entry->ref_cnt == 0 && entry->rule_cnt == 0) {
@@ -1371,7 +1381,7 @@
if (rtrule->rule.hdr_hdl) {
hdr = ipa_id_find(rtrule->rule.hdr_hdl);
- if ((hdr == NULL) || (hdr->cookie != IPA_COOKIE)) {
+ if ((hdr == NULL) || (hdr->cookie != IPA_HDR_COOKIE)) {
IPAERR("rt rule does not point to valid hdr\n");
goto error;
}
@@ -1383,7 +1393,7 @@
goto error;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
goto error;
}
diff --git a/drivers/power/qcom/msm-core.c b/drivers/power/qcom/msm-core.c
index 93248b9..3cbda0b 100644
--- a/drivers/power/qcom/msm-core.c
+++ b/drivers/power/qcom/msm-core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015,2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -349,11 +349,16 @@
int ret;
struct cpu_activity_info *node;
struct cpu_static_info *sp, *clear_sp;
- int mpidr = (argp->cluster << 8);
- int cpumask = argp->cpumask;
+ int cpumask, cluster, mpidr;
int cpu = num_possible_cpus();
- pr_debug("cpumask %d, cluster: %d\n", argp->cpumask, argp->cluster);
+ get_user(cpumask, &argp->cpumask);
+ get_user(cluster, &argp->cluster);
+ mpidr = cluster << 8;
+
+ pr_debug("%s: cpumask %d, cluster: %d\n", __func__, cpumask,
+ cluster);
+
for (i = 0; i < MAX_CORES_PER_CLUSTER; i++, cpumask >>= 1) {
if (!(cpumask & 0x01))
continue;
@@ -376,9 +381,10 @@
if (!sp)
return -ENOMEM;
-
+ mutex_lock(&policy_update_mutex);
sp->power = allocate_2d_array_uint32_t(node->sp->num_of_freqs);
if (IS_ERR_OR_NULL(sp->power)) {
+ mutex_unlock(&policy_update_mutex);
ret = PTR_ERR(sp->power);
kfree(sp);
return ret;
@@ -397,12 +403,12 @@
/* Copy the same power values for all the cpus in the cpumask
* argp->cpumask within the cluster (argp->cluster)
*/
+ get_user(cpumask, &argp->cpumask);
spin_lock(&update_lock);
- cpumask = argp->cpumask;
for (i = 0; i < MAX_CORES_PER_CLUSTER; i++, cpumask >>= 1) {
if (!(cpumask & 0x01))
continue;
- mpidr = (argp->cluster << CLUSTER_OFFSET_FOR_MPIDR);
+ mpidr = (cluster << CLUSTER_OFFSET_FOR_MPIDR);
mpidr |= i;
for_each_possible_cpu(cpu) {
if (!(cpu_logical_map(cpu) == mpidr))
@@ -421,11 +427,13 @@
}
}
spin_unlock(&update_lock);
+ mutex_unlock(&policy_update_mutex);
activate_power_table = true;
return 0;
failed:
+ mutex_unlock(&policy_update_mutex);
for (i = 0; i < TEMP_DATA_POINTS; i++)
kfree(sp->power[i]);
kfree(sp->power);
diff --git a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.c
index 3ade903..5bac25bb 100644
--- a/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.c
+++ b/drivers/staging/qcacld-2.0/CORE/CLD_TXRX/TLSHIM/tl_shim.c
@@ -552,6 +552,16 @@
rx_pkt->pkt_meta.mpdu_hdr_len;
/*
+ * If the mpdu_data_len is greater than Max (2k), drop the frame
+ */
+ if (rx_pkt->pkt_meta.mpdu_data_len > WMA_MAX_MGMT_MPDU_LEN) {
+ TLSHIM_LOGE("Data Len %d greater than max, dropping frame",
+ rx_pkt->pkt_meta.mpdu_data_len);
+ vos_mem_free(rx_pkt);
+ return 0;
+ }
+
+ /*
* saved_beacon means this beacon is a duplicate of one
* sent earlier. roamCandidateInd flag is used to indicate to
* PE that roam scan finished and a better candidate AP
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_oemdata.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_oemdata.c
index b0c844e..2a982b9 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_oemdata.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_oemdata.c
@@ -893,6 +893,7 @@
static void oem_cmd_handler(const void *data, int data_len, void *ctx, int pid)
{
tAniMsgHdr *msg_hdr;
+ int msg_len;
int ret;
struct nlattr *tb[CLD80211_ATTR_MAX + 1];
@@ -902,6 +903,10 @@
return;
}
+ /*
+ * audit note: it is ok to pass a NULL policy here since only
+ * one attribute is parsed and it is explicitly validated
+ */
if (nla_parse(tb, CLD80211_ATTR_MAX, data, data_len, NULL)) {
hddLog(LOGE, FL("Invalid ATTR"));
return;
@@ -912,14 +917,22 @@
return;
}
- msg_hdr = (tAniMsgHdr *)nla_data(tb[CLD80211_ATTR_DATA]);
- if (!msg_hdr) {
- hddLog(LOGE, FL("msg_hdr null"));
+ msg_len = nla_len(tb[CLD80211_ATTR_DATA]);
+ if (msg_len < sizeof(*msg_hdr)) {
+ hddLog(LOGE, FL("runt ATTR_DATA size %d"), msg_len);
send_oem_err_rsp_nlink_msg(pid, OEM_ERR_NULL_MESSAGE_HEADER);
return;
}
- oem_msg_callback(msg_hdr, nla_len(tb[CLD80211_ATTR_DATA]), pid);
+ msg_hdr = nla_data(tb[CLD80211_ATTR_DATA]);
+ if (msg_len < (sizeof(*msg_hdr) + msg_hdr->length)) {
+ hddLog(LOGE, FL("Invalid nl msg len %d, msg hdr len %d"),
+ msg_len, msg_hdr->length);
+ send_oem_err_rsp_nlink_msg(pid, OEM_ERR_INVALID_MESSAGE_LENGTH);
+ return;
+ }
+
+ oem_msg_callback(msg_hdr, nla_len(tb[CLD80211_ATTR_DATA]), pid);
return;
}
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h
index 215f9c6..ab96e29 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/inc/sirMacProtDef.h
@@ -585,6 +585,7 @@
#define SIR_MAC_MAX_NUM_OF_DEFAULT_KEYS 4
#define SIR_MAC_KEY_LENGTH 13 // WEP Maximum key length size
#define SIR_MAC_AUTH_CHALLENGE_LENGTH 253
+#define SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH 128
#define SIR_MAC_WEP_IV_LENGTH 4
#define SIR_MAC_WEP_ICV_LENGTH 4
#define SIR_MAC_CHALLENGE_ID_LEN 2
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h
index 10f1872..0b100ae 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/include/dot11f.h
@@ -36,7 +36,7 @@
*
*
* This file was automatically generated by 'framesc'
- * Tue Jul 4 11:07:27 2017 from the following file(s):
+ * Wed Jul 12 16:02:49 2017 from the following file(s):
*
* dot11f.frms
*
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessActionFrame.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessActionFrame.c
index d03ae85..293bbca 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessActionFrame.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessActionFrame.c
@@ -2422,6 +2422,12 @@
pHdr = WDA_GET_RX_MAC_HEADER(pRxPacketInfo);
frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
+ if (frameLen < sizeof(pPubAction)) {
+ limLog(pMac, LOG1,
+ FL("Received action frame of invalid len %d"), frameLen);
+ break;
+ }
+
//Check if it is a P2P public action frame.
if (vos_mem_compare(pPubAction->Oui, P2POui, 4))
{
@@ -2599,6 +2605,12 @@
pHdr = WDA_GET_RX_MAC_HEADER(pBd);
frameLen = WDA_GET_RX_PAYLOAD_LEN(pBd);
+ if (frameLen < sizeof(pActionHdr)) {
+ limLog(pMac, LOG1,
+ FL("Received action frame of invalid len %d"), frameLen);
+ break;
+ }
+
//Check if it is a P2P public action frame.
if (vos_mem_compare(pActionHdr->Oui, P2POui, 4))
{
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAuthFrame.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
index 17cb712..c5c72aa 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessAuthFrame.c
@@ -297,7 +297,8 @@
goto free;
}
- if (frameLen < LIM_ENCR_AUTH_BODY_LEN)
+ if ((frameLen < LIM_ENCR_AUTH_BODY_LEN_SAP) ||
+ (frameLen > LIM_ENCR_AUTH_BODY_LEN_SAP))
{
// Log error
limLog(pMac, LOGE,
@@ -973,9 +974,9 @@
pAuthNode->fTimerStarted = 1;
/*
- * get random bytes and use as challenge text.
+ * get random bytes and use as challenge text
*/
- if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( 0, (tANI_U8 *)challengeTextArray, SIR_MAC_AUTH_CHALLENGE_LENGTH ) ) )
+ if( !VOS_IS_STATUS_SUCCESS( vos_rand_get_bytes( 0, (tANI_U8 *)challengeTextArray, SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH ) ) )
{
limLog(pMac, LOGE,FL("Challenge text preparation failed in limProcessAuthFrame"));
goto free;
@@ -997,11 +998,12 @@
pRxAuthFrameBody->authTransactionSeqNumber + 1;
authFrame->authStatusCode =
eSIR_MAC_SUCCESS_STATUS;
+
authFrame->type = SIR_MAC_CHALLENGE_TEXT_EID;
- authFrame->length = SIR_MAC_AUTH_CHALLENGE_LENGTH;
+ authFrame->length = SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH;
vos_mem_copy(authFrame->challengeText,
pAuthNode->challengeText,
- SIR_MAC_AUTH_CHALLENGE_LENGTH);
+ SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH);
limSendAuthMgmtFrame(
pMac, authFrame,
@@ -1603,7 +1605,7 @@
if (vos_mem_compare(pRxAuthFrameBody->challengeText,
pAuthNode->challengeText,
- SIR_MAC_AUTH_CHALLENGE_LENGTH))
+ SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH))
{
/// Challenge match. STA is autheticated !
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index bb43c12..41c7709 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -6590,8 +6590,17 @@
vos_mem_copy(vendor_ie, pModifyIE->pIEBuffer,
pModifyIE->ieBufferlength);
} else {
- uint16_t new_length = pModifyIE->ieBufferlength + *pDstDataLen;
- uint8_t *new_ptr = vos_mem_malloc(new_length);
+ uint8_t *new_ptr;
+ uint16_t new_length;
+
+ if (USHRT_MAX - pModifyIE->ieBufferlength < *pDstDataLen) {
+ limLog(pMac,LOGE,FL("U16 overflow due to %d + %d"),
+ pModifyIE->ieBufferlength, *pDstDataLen);
+ return false;
+ }
+
+ new_length = pModifyIE->ieBufferlength + *pDstDataLen;
+ new_ptr = vos_mem_malloc(new_length);
if (NULL == new_ptr) {
limLog(pMac, LOGE, FL("Memory allocation failed."));
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h
index 4fb961c..3dd987b 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSecurityUtils.h
@@ -48,6 +48,11 @@
SIR_MAC_WEP_ICV_LENGTH + \
SIR_MAC_CHALLENGE_ID_LEN)
+#define LIM_ENCR_AUTH_BODY_LEN_SAP (SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH + \
+ SIR_MAC_CHALLENGE_ID_LEN + \
+ SIR_MAC_AUTH_FRAME_INFO_LEN + \
+ SIR_MAC_WEP_IV_LENGTH + \
+ SIR_MAC_WEP_ICV_LENGTH)
struct tLimPreAuthNode;
tANI_U8 limIsAuthAlgoSupported(tpAniSirGlobal, tAniAuthType, tpPESession);
diff --git a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c
index aaa8803..2d9b319 100644
--- a/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c
+++ b/drivers/staging/qcacld-2.0/CORE/MAC/src/pe/lim/limSendManagementFrames.c
@@ -3435,10 +3435,11 @@
* transaction number, status code and 128 bytes
* for challenge text.
*/
-
+ bodyLen = SIR_MAC_AUTH_FRAME_INFO_LEN +
+ SIR_MAC_SAP_AUTH_CHALLENGE_LENGTH +
+ SIR_MAC_CHALLENGE_ID_LEN;
frameLen = sizeof(tSirMacMgmtHdr) +
- sizeof(tSirMacAuthFrame);
- bodyLen = sizeof(tSirMacAuthFrameBody);
+ bodyLen;
}
break;
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
index eaa9a37..afd6d82 100644
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
@@ -4611,7 +4611,8 @@
wmi_rate_stats *rate_stats;
tSirLLStatsResults *link_stats_results;
u_int8_t *results, *t_peer_stats, *t_rate_stats;
- u_int32_t count, num_rates=0, rate_cnt;
+ u_int32_t count, rate_cnt;
+ uint32_t total_num_rates = 0;
u_int32_t next_res_offset, next_peer_offset, next_rate_offset;
size_t peer_info_size, peer_stats_size, rate_stats_size;
size_t link_stats_results_size;
@@ -4641,8 +4642,8 @@
* cmd_param_info contains
* wmi_peer_stats_event_fixed_param fixed_param;
* num_peers * size of(struct wmi_peer_link_stats)
- * num_rates * size of(struct wmi_rate_stats)
- * num_rates is the sum of the rates of all the peers.
+ * total_num_rates * size of(struct wmi_rate_stats)
+ * total_num_rates is the sum of the rates of all the peers.
*/
fixed_param = param_tlvs->fixed_param;
peer_stats = param_tlvs->peer_stats;
@@ -4655,22 +4656,33 @@
}
do {
- if (peer_stats->num_rates >
- WMA_SVC_MSG_MAX_SIZE/sizeof(wmi_rate_stats)) {
- excess_data = true;
- break;
- } else {
- buf_len = peer_stats->num_rates *
- sizeof(wmi_rate_stats);
- }
if (fixed_param->num_peers >
WMA_SVC_MSG_MAX_SIZE/sizeof(wmi_peer_link_stats)) {
excess_data = true;
break;
} else {
- buf_len += fixed_param->num_peers *
+ buf_len = fixed_param->num_peers *
sizeof(wmi_peer_link_stats);
}
+ temp_peer_stats = (wmi_peer_link_stats *) peer_stats;
+ for (count = 0; count < fixed_param->num_peers; count++) {
+ if (temp_peer_stats->num_rates >
+ WMA_SVC_MSG_MAX_SIZE / sizeof(wmi_rate_stats)) {
+ excess_data = true;
+ break;
+ } else {
+ total_num_rates += temp_peer_stats->num_rates;
+ if (total_num_rates >
+ WMA_SVC_MSG_MAX_SIZE /
+ sizeof(wmi_rate_stats)) {
+ excess_data = true;
+ break;
+ }
+ buf_len += temp_peer_stats->num_rates *
+ sizeof(wmi_rate_stats);
+ }
+ temp_peer_stats++;
+ }
} while (0);
if (excess_data ||
@@ -4681,21 +4693,12 @@
return -EINVAL;
}
- /*
- * num_rates - sum of the rates of all the peers
- */
- temp_peer_stats = (wmi_peer_link_stats*)peer_stats;
- for (count = 0; count < fixed_param->num_peers; count++) {
- num_rates += temp_peer_stats->num_rates;
- temp_peer_stats++;
- }
-
peer_stats_size = sizeof(tSirWifiPeerStat);
peer_info_size = sizeof(tSirWifiPeerInfo);
rate_stats_size = sizeof(tSirWifiRateStat);
link_stats_results_size = sizeof(*link_stats_results) + peer_stats_size +
(fixed_param->num_peers * peer_info_size) +
- (num_rates * rate_stats_size);
+ (total_num_rates * rate_stats_size);
link_stats_results = vos_mem_malloc(link_stats_results_size);
if (NULL == link_stats_results ) {
@@ -5310,6 +5313,12 @@
WMA_LOGE("%s: Invalid beacon buffer", __func__);
return;
}
+ if (WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info) >
+ WMI_P2P_MAX_NOA_DESCRIPTORS) {
+ WMA_LOGE("%s: Too many descriptors %d", __func__,
+ WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info));
+ return;
+ }
wmi_buf = wmi_buf_alloc(wma->wmi_handle, sizeof(*cmd));
if (!wmi_buf) {
@@ -5965,6 +5974,12 @@
descriptors = WMI_UNIFIED_NOA_ATTR_NUM_DESC_GET(p2p_noa_info);
noa_ie.num_descriptors = (u_int8_t)descriptors;
+ if (noa_ie.num_descriptors > WMA_MAX_NOA_DESCRIPTORS) {
+ WMA_LOGD("Sizing down the no of desc %d to max",
+ noa_ie.num_descriptors);
+ noa_ie.num_descriptors = WMA_MAX_NOA_DESCRIPTORS;
+ }
+
WMA_LOGI("%s: index %u, oppPs %u, ctwindow %u, "
"num_descriptors = %u", __func__, noa_ie.index,
noa_ie.oppPS, noa_ie.ctwindow, noa_ie.num_descriptors);
@@ -31503,6 +31518,11 @@
nlo_event = param_buf->fixed_param;
WMA_LOGD("PNO match event received for vdev %d",
nlo_event->vdev_id);
+ if (nlo_event->vdev_id >= wma->max_bssid) {
+ WMA_LOGE("Invalid vdev id in the NLO event %d",
+ nlo_event->vdev_id);
+ return -EINVAL;
+ }
node = &wma->interfaces[nlo_event->vdev_id];
if (node)
@@ -31651,7 +31671,8 @@
/* FW mapped vdev from ID
* vdev_map = (1 << vdev_id)
* So, host should unmap to ID */
- for (vdev_id = 0; vdev_map != 0; vdev_id++)
+ for (vdev_id = 0; vdev_map != 0 && vdev_id < wma->max_bssid;
+ vdev_id++)
{
if (!(vdev_map & 0x1))
{
@@ -34742,6 +34763,14 @@
currentSeq);
}
+ if ((datalen > MAX_UTF_EVENT_LENGTH) ||
+ (wma_handle->utf_event_info.offset >
+ (MAX_UTF_EVENT_LENGTH - datalen))) {
+ WMA_LOGE("Excess data from firmware, offset:%zu, len:%d",
+ wma_handle->utf_event_info.offset, datalen);
+ return -EINVAL;
+ }
+
memcpy(&wma_handle->utf_event_info.data[wma_handle->utf_event_info.offset],
&data[sizeof(segHdrInfo)],
datalen);
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.h
index f5f3a72..80b9564 100644
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.h
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.h
@@ -101,6 +101,8 @@
#define FRAGMENT_SIZE 3072
+#define WMA_MAX_MGMT_MPDU_LEN 2000
+
#define WMA_INVALID_VDEV_ID 0xFF
#define MAX_MEM_CHUNKS 32
#define WMA_MAX_VDEV_SIZE 20
diff --git a/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Api.c b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Api.c
index a4e85e6..75fca9e 100644
--- a/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Api.c
+++ b/drivers/staging/qcacld-2.0/CORE/SME/src/sme_common/sme_Api.c
@@ -1633,7 +1633,7 @@
eHalStatus status;
tANI_BOOLEAN ret = eANI_BOOLEAN_FALSE;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
- tANI_U8 ch_list[WNI_CFG_VALID_CHANNEL_LIST] = {0};
+ tANI_U8 ch_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
tANI_U8 count, valid_count = 0;
vos_msg_t msg;
diff --git a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c
index c19e9c0..7a94d1f 100644
--- a/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c
+++ b/drivers/staging/qcacld-2.0/CORE/SYS/legacy/src/utils/src/dot11f.c
@@ -35,7 +35,7 @@
*
*
* This file was automatically generated by 'framesc'
- * Tue Jul 4 11:07:27 2017 from the following file(s):
+ * Wed Jul 12 16:02:49 2017 from the following file(s):
*
* dot11f.frms
*
@@ -476,7 +476,7 @@
{
const tIEDefn *pIe, *pIeFirst;
tANI_U8 *pBufRemaining = pBuf;
- tANI_U8 len = 0;
+ tANI_U32 len = 0;
(void)pCtx;
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 6524383..98a8750 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -511,15 +511,23 @@
} else if (header->bDescriptorType ==
USB_DT_INTERFACE_ASSOCIATION) {
+ struct usb_interface_assoc_descriptor *d;
+
+ d = (struct usb_interface_assoc_descriptor *)header;
+ if (d->bLength < USB_DT_INTERFACE_ASSOCIATION_SIZE) {
+ dev_warn(ddev,
+ "config %d has an invalid interface association descriptor of length %d, skipping\n",
+ cfgno, d->bLength);
+ continue;
+ }
+
if (iad_num == USB_MAXIADS) {
dev_warn(ddev, "found more Interface "
"Association Descriptors "
"than allocated for in "
"configuration %d\n", cfgno);
} else {
- config->intf_assoc[iad_num] =
- (struct usb_interface_assoc_descriptor
- *)header;
+ config->intf_assoc[iad_num] = d;
iad_num++;
}
@@ -820,10 +828,12 @@
for (i = 0; i < num; i++) {
buffer += length;
cap = (struct usb_dev_cap_header *)buffer;
- length = cap->bLength;
- if (total_len < length)
+ if (total_len < sizeof(*cap) || total_len < cap->bLength) {
+ dev->bos->desc->bNumDeviceCaps = i;
break;
+ }
+ length = cap->bLength;
total_len -= length;
if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) {
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 5f3bcd3..f3bbe21 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -188,6 +188,7 @@
kfree(tty);
reset_open_count:
port->port.count = 0;
+ info->port = NULL;
usb_autopm_put_interface(serial->interface);
error_get_interface:
usb_serial_put(serial);
diff --git a/include/uapi/linux/usb/ch9.h b/include/uapi/linux/usb/ch9.h
index fca1db3..9f0fd880 100644
--- a/include/uapi/linux/usb/ch9.h
+++ b/include/uapi/linux/usb/ch9.h
@@ -720,6 +720,7 @@
__u8 iFunction;
} __attribute__ ((packed));
+#define USB_DT_INTERFACE_ASSOCIATION_SIZE 8
/*-------------------------------------------------------------------------*/
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index cc05702..60f5c7b 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1320,10 +1320,6 @@
mutex_lock(&fanout_mutex);
- err = -EINVAL;
- if (!po->running)
- goto out;
-
err = -EALREADY;
if (po->fanout)
goto out;
@@ -1361,7 +1357,10 @@
list_add(&match->list, &fanout_list);
}
err = -EINVAL;
- if (match->type == type &&
+
+ spin_lock(&po->bind_lock);
+ if (po->running &&
+ match->type == type &&
match->prot_hook.type == po->prot_hook.type &&
match->prot_hook.dev == po->prot_hook.dev) {
err = -ENOSPC;
@@ -1373,6 +1372,13 @@
err = 0;
}
}
+ spin_unlock(&po->bind_lock);
+
+ if (err && !atomic_read(&match->sk_ref)) {
+ list_del(&match->list);
+ kfree(match);
+ }
+
out:
mutex_unlock(&fanout_mutex);
return err;
@@ -2508,17 +2514,20 @@
static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protocol)
{
struct packet_sock *po = pkt_sk(sk);
+ int ret = 0;
+
+ lock_sock(sk);
+
+ spin_lock(&po->bind_lock);
if (po->fanout) {
if (dev)
dev_put(dev);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_unlock;
}
- lock_sock(sk);
-
- spin_lock(&po->bind_lock);
unregister_prot_hook(sk, true);
po->num = protocol;
@@ -2545,7 +2554,7 @@
out_unlock:
spin_unlock(&po->bind_lock);
release_sock(sk);
- return 0;
+ return ret;
}
/*
@@ -3176,14 +3185,19 @@
if (optlen != sizeof(val))
return -EINVAL;
- if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
- return -EBUSY;
if (copy_from_user(&val, optval, sizeof(val)))
return -EFAULT;
if (val > INT_MAX)
return -EINVAL;
- po->tp_reserve = val;
- return 0;
+ lock_sock(sk);
+ if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
+ ret = -EBUSY;
+ } else {
+ po->tp_reserve = val;
+ ret = 0;
+ }
+ release_sock(sk);
+ return ret;
}
case PACKET_LOSS:
{
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index 7a2a8a1..f256c96 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -115,6 +115,7 @@
bool use_dsp_gapless_mode;
struct msm_compr_dec_params *dec_params[MSM_FRONTEND_DAI_MAX];
struct msm_compr_ch_map *ch_map[MSM_FRONTEND_DAI_MAX];
+ bool is_in_use[MSM_FRONTEND_DAI_MAX];
};
struct msm_compr_audio {
@@ -965,11 +966,16 @@
{
struct snd_compr_runtime *runtime = cstream->runtime;
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
- struct msm_compr_audio *prtd;
+ struct msm_compr_audio *prtd = NULL;
struct msm_compr_pdata *pdata =
snd_soc_platform_get_drvdata(rtd->platform);
pr_debug("%s\n", __func__);
+ if (pdata->is_in_use[rtd->dai_link->be_id] == true) {
+ pr_err("%s: %s is already in use,err: %d ",
+ __func__, rtd->dai_link->cpu_dai_name, -EBUSY);
+ return -EBUSY;
+ }
prtd = kzalloc(sizeof(struct msm_compr_audio), GFP_KERNEL);
if (prtd == NULL) {
pr_err("Failed to allocate memory for msm_compr_audio\n");
@@ -981,7 +987,7 @@
pdata->cstream[rtd->dai_link->be_id] = cstream;
pdata->audio_effects[rtd->dai_link->be_id] =
kzalloc(sizeof(struct msm_compr_audio_effects), GFP_KERNEL);
- if (!pdata->audio_effects[rtd->dai_link->be_id]) {
+ if (pdata->audio_effects[rtd->dai_link->be_id] == NULL) {
pr_err("%s: Could not allocate memory for effects\n", __func__);
pdata->cstream[rtd->dai_link->be_id] = NULL;
kfree(prtd);
@@ -989,10 +995,11 @@
}
pdata->dec_params[rtd->dai_link->be_id] =
kzalloc(sizeof(struct msm_compr_dec_params), GFP_KERNEL);
- if (!pdata->dec_params[rtd->dai_link->be_id]) {
+ if (pdata->dec_params[rtd->dai_link->be_id] == NULL) {
pr_err("%s: Could not allocate memory for dec params\n",
__func__);
kfree(pdata->audio_effects[rtd->dai_link->be_id]);
+ pdata->audio_effects[rtd->dai_link->be_id] = NULL;
pdata->cstream[rtd->dai_link->be_id] = NULL;
kfree(prtd);
return -ENOMEM;
@@ -1002,7 +1009,9 @@
if (!prtd->audio_client) {
pr_err("%s: Could not allocate memory for client\n", __func__);
kfree(pdata->audio_effects[rtd->dai_link->be_id]);
+ pdata->audio_effects[rtd->dai_link->be_id] = NULL;
kfree(pdata->dec_params[rtd->dai_link->be_id]);
+ pdata->dec_params[rtd->dai_link->be_id] = NULL;
pdata->cstream[rtd->dai_link->be_id] = NULL;
kfree(prtd);
return -ENOMEM;
@@ -1062,7 +1071,7 @@
} else {
pr_err("%s: Unsupported stream type", __func__);
}
-
+ pdata->is_in_use[rtd->dai_link->be_id] = true;
return 0;
}
@@ -1155,11 +1164,15 @@
q6asm_audio_client_buf_free_contiguous(dir, ac);
q6asm_audio_client_free(ac);
-
- kfree(pdata->audio_effects[soc_prtd->dai_link->be_id]);
- pdata->audio_effects[soc_prtd->dai_link->be_id] = NULL;
- kfree(pdata->dec_params[soc_prtd->dai_link->be_id]);
- pdata->dec_params[soc_prtd->dai_link->be_id] = NULL;
+ if (pdata->audio_effects[soc_prtd->dai_link->be_id] != NULL) {
+ kfree(pdata->audio_effects[soc_prtd->dai_link->be_id]);
+ pdata->audio_effects[soc_prtd->dai_link->be_id] = NULL;
+ }
+ if (pdata->dec_params[soc_prtd->dai_link->be_id] != NULL) {
+ kfree(pdata->dec_params[soc_prtd->dai_link->be_id]);
+ pdata->dec_params[soc_prtd->dai_link->be_id] = NULL;
+ }
+ pdata->is_in_use[soc_prtd->dai_link->be_id] = false;
kfree(prtd);
runtime->private_data = NULL;
@@ -2636,6 +2649,7 @@
pdata->dec_params[i] = NULL;
pdata->cstream[i] = NULL;
pdata->ch_map[i] = NULL;
+ pdata->is_in_use[i] = false;
}
/*
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 1b091e0..1d30f3e 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -222,6 +222,7 @@
struct usb_interface *usb_iface;
void *control_header;
int i, protocol;
+ int rest_bytes;
usb_iface = usb_ifnum_to_if(dev, ctrlif);
if (!usb_iface) {
@@ -248,6 +249,15 @@
return -EINVAL;
}
+ rest_bytes = (void *)(host_iface->extra + host_iface->extralen) -
+ control_header;
+
+ /* just to be sure -- this shouldn't hit at all */
+ if (rest_bytes <= 0) {
+ dev_err(&dev->dev, "invalid control header\n");
+ return -EINVAL;
+ }
+
switch (protocol) {
default:
snd_printdd(KERN_WARNING "unknown interface protocol %#02x, assuming v1\n",
@@ -257,11 +267,21 @@
case UAC_VERSION_1: {
struct uac1_ac_header_descriptor *h1 = control_header;
+ if (rest_bytes < sizeof(*h1)) {
+ dev_err(&dev->dev, "too short v1 buffer descriptor\n");
+ return -EINVAL;
+ }
+
if (!h1->bInCollection) {
snd_printk(KERN_INFO "skipping empty audio interface (v1)\n");
return -EINVAL;
}
+ if (rest_bytes < h1->bLength) {
+ dev_err(&dev->dev, "invalid buffer length (v1)\n");
+ return -EINVAL;
+ }
+
if (h1->bLength < sizeof(*h1) + h1->bInCollection) {
snd_printk(KERN_ERR "invalid UAC_HEADER (v1)\n");
return -EINVAL;
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index f7ad0a0..1e2620a 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -2072,6 +2072,9 @@
static void snd_usb_mixer_free(struct usb_mixer_interface *mixer)
{
+ /* kill pending URBs */
+ snd_usb_mixer_disconnect(&mixer->list);
+
kfree(mixer->id_elems);
if (mixer->urb) {
kfree(mixer->urb->transfer_buffer);
@@ -2418,6 +2421,11 @@
struct usb_mixer_interface *mixer;
mixer = list_entry(p, struct usb_mixer_interface, list);
- usb_kill_urb(mixer->urb);
- usb_kill_urb(mixer->rc_urb);
+ if (mixer->disconnected)
+ return;
+ if (mixer->urb)
+ usb_kill_urb(mixer->urb);
+ if (mixer->rc_urb)
+ usb_kill_urb(mixer->rc_urb);
+ mixer->disconnected = true;
}
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index aab80df..041b571 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -23,6 +23,7 @@
u8 audigy2nx_leds[3];
u8 xonar_u1_status;
+ bool disconnected;
};
#define MAX_CHANNELS 16 /* max logical channels */