aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWei Wang <wvw@google.com>2018-01-12 12:01:10 -0800
committerWei Wang <wvw@google.com>2018-01-12 13:44:31 -0800
commit9142a68b659e77c2f8830927fe3f53720a49c810 (patch)
tree3b3f6d031b606a4ce8224449756ffd85c3afed1c
parent41cf64bd3d18d0a71bff388893b5c0b232b42be4 (diff)
parent1a3a7631b1fc91d208d4ab4fa48255e1cf9eaab2 (diff)
Merge branch 'android-msm-angler-3.10-security-next' into android-msm-angler-3.10android-8.1.0_r0.36android-8.1.0_r0.34
March 2018.1 Change-Id: I88bed6a83a528b73b1bc5cfea849af2e31a49898
-rw-r--r--drivers/char/diag/diag_debugfs.c7
-rw-r--r--drivers/char/diag/diagchar_core.c6
-rw-r--r--drivers/hid/usbhid/hid-core.c12
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c3
-rw-r--r--drivers/platform/msm/ipa/ipa_flt.c18
-rw-r--r--drivers/platform/msm/ipa/ipa_hdr.c38
-rw-r--r--drivers/platform/msm/ipa/ipa_i.h16
-rw-r--r--drivers/platform/msm/ipa/ipa_rt.c36
-rw-r--r--drivers/power/qcom/msm-core.c22
-rw-r--r--drivers/usb/core/config.c20
-rw-r--r--drivers/usb/serial/console.c1
-rw-r--r--include/uapi/linux/usb/ch9.h1
-rw-r--r--net/packet/af_packet.c42
-rw-r--r--sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c32
-rw-r--r--sound/usb/card.c20
-rw-r--r--sound/usb/mixer.c12
-rw-r--r--sound/usb/mixer.h1
17 files changed, 212 insertions, 75 deletions
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
index 6916507ec2b1..5160c7be9260 100644
--- a/drivers/char/diag/diag_debugfs.c
+++ b/drivers/char/diag/diag_debugfs.c
@@ -36,7 +36,7 @@ static int diag_dbgfs_bridgeinfo_index;
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 @@ static ssize_t diag_dbgfs_read_dcistats(struct file *file,
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 @@ static ssize_t diag_dbgfs_read_dcistats(struct file *file,
}
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 @@ int diag_debugfs_init(void)
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 @@ void diag_debugfs_cleanup(void)
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 c9461d65d7e6..be581c25ef91 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1051,14 +1051,18 @@ static int diag_ioctl_lsm_deinit(void)
{
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 ada164e1b3a1..60d77af9e027 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -1016,6 +1016,8 @@ static int usbhid_parse(struct hid_device *hid)
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 @@ static int usbhid_parse(struct hid_device *hid)
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 0390e0e60dea..40d731bb858c 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 @@ static long msm_flash_subdev_do_ioctl(
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 72342c2c568b..54328b7e8777 100644
--- a/drivers/platform/msm/ipa/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_flt.c
@@ -1017,7 +1017,7 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
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 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
}
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 @@ static int __ipa_add_flt_rule(struct ipa_flt_tbl *tbl, enum ipa_ip_type ip,
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 @@ static int __ipa_del_flt_rule(u32 rule_hdl)
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -1111,7 +1117,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
goto error;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_FLT_COOKIE) {
IPAERR("bad params\n");
goto error;
}
@@ -1132,7 +1138,7 @@ static int __ipa_mdfy_flt_rule(struct ipa_flt_rule_mdfy *frule,
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 52be0fbc676b..92974c7878ed 100644
--- a/drivers/platform/msm/ipa/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_hdr.c
@@ -469,7 +469,7 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
{
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 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
}
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 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
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 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
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 @@ static int __ipa_add_hdr_proc_ctx(struct ipa_hdr_proc_ctx_add *proc_ctx,
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 @@ bad_len:
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 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
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 @@ static int __ipa_add_hdr(struct ipa_hdr_add *hdr)
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 @@ fail_add_proc_ctx:
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 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl,
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 @@ int __ipa_del_hdr(u32 hdr_hdl, bool by_user)
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 @@ int ipa_put_hdr(u32 hdr_hdl)
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 7c4deca1ba41..916bfdb11d83 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_mem_buffer {
*/
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_flt_entry {
*/
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_rt_tbl {
*/
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 @@ struct ipa_hdr_entry {
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_add_hdr_cmd_seq {
*/
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_flt_tbl {
*/
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 81c6331da8a5..ba28ba7b04fd 100644
--- a/drivers/platform/msm/ipa/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_rt.c
@@ -839,7 +839,7 @@ static struct ipa_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
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 @@ static struct ipa_rt_tbl *__ipa_add_rt_tbl(enum ipa_ip_type ip,
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 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry)
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 @@ static int __ipa_del_rt_tbl(struct ipa_rt_tbl *entry)
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 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
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 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
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 @@ static int __ipa_add_rt_rule(enum ipa_ip_type ip, const char *name,
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 @@ int __ipa_del_rt_rule(u32 rule_hdl)
return -EINVAL;
}
- if (entry->cookie != IPA_COOKIE) {
+ if (entry->cookie != IPA_RT_RULE_COOKIE) {
IPAERR("bad params\n");
return -EINVAL;
}
@@ -1288,7 +1295,7 @@ int ipa_get_rt_tbl(struct ipa_ioc_get_rt_tbl *lookup)
}
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 @@ int ipa_put_rt_tbl(u32 rt_tbl_hdl)
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 @@ int ipa_put_rt_tbl(u32 rt_tbl_hdl)
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 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
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 @@ static int __ipa_mdfy_rt_rule(struct ipa_rt_rule_mdfy *rtrule)
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 93248b9db7ad..3cbda0b58bfb 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 @@ static int update_userspace_power(struct sched_params __user *argp)
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 @@ static int update_userspace_power(struct sched_params __user *argp)
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 @@ static int update_userspace_power(struct sched_params __user *argp)
/* 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 @@ static int update_userspace_power(struct sched_params __user *argp)
}
}
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/usb/core/config.c b/drivers/usb/core/config.c
index 652438325197..98a87503378f 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -511,15 +511,23 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx,
} 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 @@ int usb_get_bos_descriptor(struct usb_device *dev)
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 5f3bcd31e204..f3bbe210119d 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -188,6 +188,7 @@ static int usb_console_setup(struct console *co, char *options)
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 fca1db35ac0d..9f0fd8800280 100644
--- a/include/uapi/linux/usb/ch9.h
+++ b/include/uapi/linux/usb/ch9.h
@@ -720,6 +720,7 @@ struct usb_interface_assoc_descriptor {
__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 cc05702529e4..60f5c7b63dcb 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1320,10 +1320,6 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
mutex_lock(&fanout_mutex);
- err = -EINVAL;
- if (!po->running)
- goto out;
-
err = -EALREADY;
if (po->fanout)
goto out;
@@ -1361,7 +1357,10 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
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 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
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_release(struct socket *sock)
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 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc
out_unlock:
spin_unlock(&po->bind_lock);
release_sock(sk);
- return 0;
+ return ret;
}
/*
@@ -3176,14 +3185,19 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
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 37f239d98720..992049a29679 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 @@ struct msm_compr_pdata {
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 {
@@ -960,11 +961,16 @@ static int msm_compr_open(struct snd_compr_stream *cstream)
{
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");
@@ -976,7 +982,7 @@ static int msm_compr_open(struct snd_compr_stream *cstream)
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);
@@ -984,10 +990,11 @@ static int msm_compr_open(struct snd_compr_stream *cstream)
}
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;
@@ -997,7 +1004,9 @@ static int msm_compr_open(struct snd_compr_stream *cstream)
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;
@@ -1057,7 +1066,7 @@ static int msm_compr_open(struct snd_compr_stream *cstream)
} else {
pr_err("%s: Unsupported stream type", __func__);
}
-
+ pdata->is_in_use[rtd->dai_link->be_id] = true;
return 0;
}
@@ -1150,11 +1159,15 @@ static int msm_compr_free(struct snd_compr_stream *cstream)
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;
@@ -2631,6 +2644,7 @@ static int msm_compr_probe(struct snd_soc_platform *platform)
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 1b091e0bbdd7..1d30f3e3c30d 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -222,6 +222,7 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
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 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
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 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
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 f7ad0a09b48c..1e2620ad9c3b 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -2072,6 +2072,9 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
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 @@ void snd_usb_mixer_disconnect(struct list_head *p)
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 aab80df201bd..041b5710a071 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -23,6 +23,7 @@ struct usb_mixer_interface {
u8 audigy2nx_leds[3];
u8 xonar_u1_status;
+ bool disconnected;
};
#define MAX_CHANNELS 16 /* max logical channels */