aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Dias <joaodias@google.com>2017-02-15 16:17:16 -0800
committerJohn Dias <joaodias@google.com>2017-02-15 16:17:16 -0800
commit086ab5b805a1da8133a58359cca964d0481c321c (patch)
tree108ee49404011085dc8a1b04c451fd208982b7e4
parentb0a9cfa5cf5e54d9a6b4dea35b355595f34bf8bc (diff)
parent941a80cf3340804e488c6ee2742e7a771bd01272 (diff)
Merge branch 'android-msm-marlin-3.18-nyc-mr1' into android-msm-marlin-3.18-nyc-mr2android-n-mr2-preview-2_r0.2android-7.1.2_r0.7android-7.1.2_r0.6android-7.1.2_r0.2
April 2017.1 Bug: 35315173 Change-Id: I8fd615cf13ee4766ad12de431dce4f545540a5e5
-rw-r--r--arch/arm64/configs/marlin_defconfig1
-rw-r--r--drivers/crypto/msm/qce50.c6
-rw-r--r--drivers/crypto/msm/qcedev.c11
-rw-r--r--drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c16
-rw-r--r--drivers/platform/msm/avtimer.c14
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_flt.c36
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_nat.c77
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_rt.c26
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_nat.c76
-rw-r--r--drivers/platform/msm/seemp_core/seemp_event_encoder.c21
-rw-r--r--drivers/platform/msm/spmi/spmi-dbgfs.c37
-rw-r--r--drivers/soc/qcom/Kconfig10
-rw-r--r--drivers/soc/qcom/kryo-l2-accessors.c6
-rwxr-xr-xdrivers/staging/android/ion/ion.c83
-rw-r--r--drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c7
-rw-r--r--drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_unified_api.h4
-rw-r--r--drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/ath_procfs.c11
-rw-r--r--drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c7
-rw-r--r--drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_unified.c4
-rw-r--r--drivers/usb/gadget/function/f_mbim.c6
-rw-r--r--drivers/video/msm/mdss/mdss_compat_utils.c4
-rw-r--r--drivers/video/msm/mdss/mdss_debug.c8
-rw-r--r--drivers/video/msm/mdss/mdss_fb.c8
-rw-r--r--drivers/video/msm/mdss/mdss_mdp.c2
-rw-r--r--drivers/video/msm/mdss/mdss_mdp_overlay.c8
-rw-r--r--fs/9p/acl.c42
-rw-r--r--fs/btrfs/acl.c6
-rw-r--r--fs/ceph/acl.c6
-rw-r--r--fs/ext2/acl.c12
-rw-r--r--fs/ext3/acl.c12
-rw-r--r--fs/ext4/acl.c12
-rw-r--r--fs/f2fs/acl.c6
-rw-r--r--fs/gfs2/acl.c12
-rw-r--r--fs/hfsplus/posix_acl.c4
-rw-r--r--fs/jffs2/acl.c9
-rw-r--r--fs/jfs/acl.c6
-rw-r--r--fs/ocfs2/acl.c18
-rw-r--r--fs/posix_acl.c31
-rw-r--r--fs/reiserfs/xattr_acl.c8
-rw-r--r--fs/sdcardfs/main.c7
-rw-r--r--fs/xfs/xfs_acl.c13
-rw-r--r--include/linux/posix_acl.h1
-rw-r--r--net/ipv4/udp.c6
-rw-r--r--net/ipv6/udp.c6
-rwxr-xr-xsound/soc/codecs/wcd9335.c7
-rw-r--r--[-rwxr-xr-x]sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c12
46 files changed, 549 insertions, 176 deletions
diff --git a/arch/arm64/configs/marlin_defconfig b/arch/arm64/configs/marlin_defconfig
index c3d9e6565b1d..7f08b8172522 100644
--- a/arch/arm64/configs/marlin_defconfig
+++ b/arch/arm64/configs/marlin_defconfig
@@ -500,7 +500,6 @@ CONFIG_GPIO_USB_DETECT=y
CONFIG_MSM_SPMI=y
CONFIG_MSM_SPMI_PMIC_ARB=y
CONFIG_MSM_QPNP_INT=y
-CONFIG_CP_ACCESS64=y
CONFIG_MSM_ADSP_LOADER=y
CONFIG_MSM_MEMORY_DUMP_V2=y
CONFIG_MSM_BOOT_STATS=y
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index b623a82051c8..5bc5f405d016 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -4904,6 +4904,12 @@ int qce_aead_req(void *handle, struct qce_req *q_req)
else
q_req->cryptlen = areq->cryptlen - authsize;
+ if ((q_req->cryptlen > UINT_MAX - areq->assoclen) ||
+ (q_req->cryptlen + areq->assoclen > UINT_MAX - ivsize)) {
+ pr_err("Integer overflow on total aead req length.\n");
+ return -EINVAL;
+ }
+
totallen = q_req->cryptlen + areq->assoclen + ivsize;
if (pce_dev->support_cmd_dscr) {
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index 433e4783d1d1..5da0c86d47ca 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1445,6 +1445,15 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req,
pr_err("%s: Invalid byte offset\n", __func__);
goto error;
}
+ total = req->byteoffset;
+ for (i = 0; i < req->entries; i++) {
+ if (total > U32_MAX - req->vbuf.src[i].len) {
+ pr_err("%s:Integer overflow on total src len\n",
+ __func__);
+ goto error;
+ }
+ total += req->vbuf.src[i].len;
+ }
}
if (req->data_len < req->byteoffset) {
@@ -1480,7 +1489,7 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req,
}
}
/* Check for sum of all dst length is equal to data_len */
- for (i = 0; i < req->entries; i++) {
+ for (i = 0, total = 0; i < req->entries; i++) {
if (req->vbuf.dst[i].len >= U32_MAX - total) {
pr_err("%s: Integer overflow on total req dst vbuf length\n",
__func__);
diff --git a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c b/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c
index 3632fc2b961b..bb4d710ea3cb 100644
--- a/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c
+++ b/drivers/misc/qcom/qdsp6v2/audio_hwacc_effects.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -29,6 +29,8 @@ struct q6audio_effects {
struct audio_client *ac;
struct msm_hwacc_effects_config config;
+ struct mutex lock;
+
atomic_t in_count;
atomic_t out_count;
@@ -230,8 +232,11 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd,
uint32_t idx = 0;
uint32_t size = 0;
+ mutex_lock(&effects->lock);
+
if (!effects->started) {
rc = -EFAULT;
+ mutex_unlock(&effects->lock);
goto ioctl_fail;
}
@@ -241,11 +246,13 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd,
if (!rc) {
pr_err("%s: write wait_event_timeout\n", __func__);
rc = -EFAULT;
+ mutex_unlock(&effects->lock);
goto ioctl_fail;
}
if (!atomic_read(&effects->out_count)) {
pr_err("%s: pcm stopped out_count 0\n", __func__);
rc = -EFAULT;
+ mutex_unlock(&effects->lock);
goto ioctl_fail;
}
@@ -255,6 +262,7 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd,
copy_from_user(bufptr, (void *)arg,
effects->config.buf_cfg.output_len)) {
rc = -EFAULT;
+ mutex_unlock(&effects->lock);
goto ioctl_fail;
}
rc = q6asm_write(effects->ac,
@@ -262,6 +270,7 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd,
0, 0, NO_TIMESTAMP);
if (rc < 0) {
rc = -EFAULT;
+ mutex_unlock(&effects->lock);
goto ioctl_fail;
}
atomic_dec(&effects->out_count);
@@ -269,6 +278,7 @@ static int audio_effects_shared_ioctl(struct file *file, unsigned cmd,
pr_err("%s: AUDIO_EFFECTS_WRITE: Buffer dropped\n",
__func__);
}
+ mutex_unlock(&effects->lock);
break;
}
case AUDIO_EFFECTS_READ: {
@@ -466,6 +476,7 @@ static long audio_effects_ioctl(struct file *file, unsigned int cmd,
break;
}
case AUDIO_EFFECTS_SET_BUF_LEN: {
+ mutex_lock(&effects->lock);
if (copy_from_user(&effects->config.buf_cfg, (void *)arg,
sizeof(effects->config.buf_cfg))) {
pr_err("%s: copy from user for AUDIO_EFFECTS_SET_BUF_LEN failed\n",
@@ -475,6 +486,7 @@ static long audio_effects_ioctl(struct file *file, unsigned int cmd,
pr_debug("%s: write buf len: %d, read buf len: %d\n",
__func__, effects->config.buf_cfg.output_len,
effects->config.buf_cfg.input_len);
+ mutex_unlock(&effects->lock);
break;
}
case AUDIO_EFFECTS_GET_BUF_AVAIL: {
@@ -719,6 +731,7 @@ static int audio_effects_release(struct inode *inode, struct file *file)
}
q6asm_audio_client_free(effects->ac);
+ mutex_destroy(&effects->lock);
kfree(effects);
pr_debug("%s: close session success\n", __func__);
@@ -749,6 +762,7 @@ static int audio_effects_open(struct inode *inode, struct file *file)
init_waitqueue_head(&effects->read_wait);
init_waitqueue_head(&effects->write_wait);
+ mutex_init(&effects->lock);
effects->opened = 0;
effects->started = 0;
diff --git a/drivers/platform/msm/avtimer.c b/drivers/platform/msm/avtimer.c
index 2bded5e83cce..4331af8890c0 100644
--- a/drivers/platform/msm/avtimer.c
+++ b/drivers/platform/msm/avtimer.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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
@@ -331,9 +331,17 @@ static long avtimer_ioctl(struct file *file, unsigned int ioctl_num,
switch (ioctl_num) {
case IOCTL_GET_AVTIMER_TICK:
{
- uint64_t avtimer_tick;
+ uint64_t avtimer_tick = 0;
+ int rc;
+
+ rc = avcs_core_query_timer(&avtimer_tick);
+
+ if (rc) {
+ pr_err("%s: Error: Invalid AV Timer tick, rc = %d\n",
+ __func__, rc);
+ return rc;
+ }
- avcs_core_query_timer(&avtimer_tick);
pr_debug_ratelimited("%s: AV Timer tick: time %llx\n",
__func__, avtimer_tick);
if (copy_to_user((void *) ioctl_param, &avtimer_tick,
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
index c36ecfef66f1..d6e563b935b6 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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
@@ -235,7 +235,7 @@ static int ipa_generate_flt_hw_rule(enum ipa_ip_type ip,
* @ip: the ip address family type
* @hdr_sz: header size
*
- * Returns: 0 on success, negative on failure
+ * Returns: size on success, negative on failure
*
* caller needs to hold any needed locks to ensure integrity
*
@@ -373,7 +373,12 @@ static int ipa_generate_flt_hw_tbl_common(enum ipa_ip_type ip, u8 *base,
((long)body &
IPA_FLT_ENTRY_MEMORY_ALLIGNMENT));
} else {
- WARN_ON(tbl->sz == 0);
+ if (tbl->sz == 0) {
+ IPAERR("tbl size is 0\n");
+ WARN_ON(1);
+ goto proc_err;
+ }
+
/* allocate memory for the flt tbl */
flt_tbl_mem.size = tbl->sz;
flt_tbl_mem.base =
@@ -460,7 +465,12 @@ static int ipa_generate_flt_hw_tbl_common(enum ipa_ip_type ip, u8 *base,
((long)body &
IPA_FLT_ENTRY_MEMORY_ALLIGNMENT));
} else {
- WARN_ON(tbl->sz == 0);
+ if (tbl->sz == 0) {
+ IPAERR("tbl size is 0\n");
+ WARN_ON(1);
+ goto proc_err;
+ }
+
/* allocate memory for the flt tbl */
flt_tbl_mem.size = tbl->sz;
flt_tbl_mem.base =
@@ -534,8 +544,15 @@ static int ipa_generate_flt_hw_tbl_v1_1(enum ipa_ip_type ip,
u8 *hdr;
u8 *body;
u8 *base;
+ int res;
+
+ res = ipa_get_flt_hw_tbl_size(ip, &hdr_sz);
+ if (res < 0) {
+ IPAERR("ipa_get_flt_hw_tbl_size failed %d\n", res);
+ return res;
+ }
- mem->size = ipa_get_flt_hw_tbl_size(ip, &hdr_sz);
+ mem->size = res;
mem->size = IPA_HW_TABLE_ALIGNMENT(mem->size);
if (mem->size == 0) {
@@ -720,6 +737,7 @@ static int ipa_generate_flt_hw_tbl_v2(enum ipa_ip_type ip,
u32 *entr;
u32 body_start_offset;
u32 hdr_top;
+ int res;
if (ip == IPA_IP_v4)
body_start_offset = IPA_MEM_PART(apps_v4_flt_ofst) -
@@ -756,7 +774,13 @@ static int ipa_generate_flt_hw_tbl_v2(enum ipa_ip_type ip,
entr++;
}
- mem->size = ipa_get_flt_hw_tbl_size(ip, &hdr_sz);
+ res = ipa_get_flt_hw_tbl_size(ip, &hdr_sz);
+ if (res < 0) {
+ IPAERR("ipa_get_flt_hw_tbl_size failed %d\n", res);
+ goto body_err;
+ }
+
+ mem->size = res;
mem->size -= hdr_sz;
mem->size = IPA_HW_TABLE_ALIGNMENT(mem->size);
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c
index 6202992c2c4e..314b09593026 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_nat.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 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
@@ -25,6 +25,16 @@
#define IPA_NAT_SHARED_MEMORY 1
#define IPA_NAT_TEMP_MEM_SIZE 128
+enum nat_table_type {
+ IPA_NAT_BASE_TBL = 0,
+ IPA_NAT_EXPN_TBL = 1,
+ IPA_NAT_INDX_TBL = 2,
+ IPA_NAT_INDEX_EXPN_TBL = 3,
+};
+
+#define NAT_TABLE_ENTRY_SIZE_BYTE 32
+#define NAT_INTEX_TABLE_ENTRY_SIZE_BYTE 4
+
static int ipa_nat_vma_fault_remap(
struct vm_area_struct *vma, struct vm_fault *vmf)
{
@@ -568,6 +578,71 @@ int ipa2_nat_dma_cmd(struct ipa_ioc_nat_dma_cmd *dma)
goto bail;
}
+ for (cnt = 0; cnt < dma->entries; cnt++) {
+ if (dma->dma[cnt].table_index >= 1) {
+ IPAERR("Invalid table index %d\n",
+ dma->dma[cnt].table_index);
+ ret = -EPERM;
+ goto bail;
+ }
+
+ switch (dma->dma[cnt].base_addr) {
+ case IPA_NAT_BASE_TBL:
+ if (dma->dma[cnt].offset >=
+ (ipa_ctx->nat_mem.size_base_tables + 1) *
+ NAT_TABLE_ENTRY_SIZE_BYTE) {
+ IPAERR("Invalid offset %d\n",
+ dma->dma[cnt].offset);
+ ret = -EPERM;
+ goto bail;
+ }
+
+ break;
+
+ case IPA_NAT_EXPN_TBL:
+ if (dma->dma[cnt].offset >=
+ ipa_ctx->nat_mem.size_expansion_tables *
+ NAT_TABLE_ENTRY_SIZE_BYTE) {
+ IPAERR("Invalid offset %d\n",
+ dma->dma[cnt].offset);
+ ret = -EPERM;
+ goto bail;
+ }
+
+ break;
+
+ case IPA_NAT_INDX_TBL:
+ if (dma->dma[cnt].offset >=
+ (ipa_ctx->nat_mem.size_base_tables + 1) *
+ NAT_INTEX_TABLE_ENTRY_SIZE_BYTE) {
+ IPAERR("Invalid offset %d\n",
+ dma->dma[cnt].offset);
+ ret = -EPERM;
+ goto bail;
+ }
+
+ break;
+
+ case IPA_NAT_INDEX_EXPN_TBL:
+ if (dma->dma[cnt].offset >=
+ ipa_ctx->nat_mem.size_expansion_tables *
+ NAT_INTEX_TABLE_ENTRY_SIZE_BYTE) {
+ IPAERR("Invalid offset %d\n",
+ dma->dma[cnt].offset);
+ ret = -EPERM;
+ goto bail;
+ }
+
+ break;
+
+ default:
+ IPAERR("Invalid base_addr %d\n",
+ dma->dma[cnt].base_addr);
+ ret = -EPERM;
+ goto bail;
+ }
+ }
+
size = sizeof(struct ipa_desc) * NUM_OF_DESC;
desc = kzalloc(size, GFP_KERNEL);
if (desc == NULL) {
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
index 0d0b73810c0b..2102f64ca6d1 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_rt.c
@@ -227,7 +227,7 @@ int __ipa_generate_rt_hw_rule_v2_6L(enum ipa_ip_type ip,
* @hdr_sz: header size
* @max_rt_idx: maximal index
*
- * Returns: 0 on success, negative on failure
+ * Returns: size on success, negative on failure
*
* caller needs to hold any needed locks to ensure integrity
*
@@ -356,7 +356,11 @@ static int ipa_generate_rt_hw_tbl_common(enum ipa_ip_type ip, u8 *base, u8 *hdr,
((long)body &
IPA_RT_ENTRY_MEMORY_ALLIGNMENT));
} else {
- WARN_ON(tbl->sz == 0);
+ if (tbl->sz == 0) {
+ IPAERR("cannot generate 0 size table\n");
+ goto proc_err;
+ }
+
/* allocate memory for the RT tbl */
rt_tbl_mem.size = tbl->sz;
rt_tbl_mem.base =
@@ -429,8 +433,15 @@ static int ipa_generate_rt_hw_tbl_v1_1(enum ipa_ip_type ip,
u8 *base;
int max_rt_idx;
int i;
+ int res;
- mem->size = ipa_get_rt_hw_tbl_size(ip, &hdr_sz, &max_rt_idx);
+ res = ipa_get_rt_hw_tbl_size(ip, &hdr_sz, &max_rt_idx);
+ if (res < 0) {
+ IPAERR("ipa_get_rt_hw_tbl_size failed %d\n", res);
+ goto error;
+ }
+
+ mem->size = res;
mem->size = (mem->size + IPA_RT_TABLE_MEMORY_ALLIGNMENT) &
~IPA_RT_TABLE_MEMORY_ALLIGNMENT;
@@ -603,6 +614,7 @@ static int ipa_generate_rt_hw_tbl_v2(enum ipa_ip_type ip,
int num_index;
u32 body_start_offset;
u32 apps_start_idx;
+ int res;
if (ip == IPA_IP_v4) {
num_index = IPA_MEM_PART(v4_apps_rt_index_hi) -
@@ -632,7 +644,13 @@ static int ipa_generate_rt_hw_tbl_v2(enum ipa_ip_type ip,
entr++;
}
- mem->size = ipa_get_rt_hw_tbl_size(ip, &hdr_sz, &max_rt_idx);
+ res = ipa_get_rt_hw_tbl_size(ip, &hdr_sz, &max_rt_idx);
+ if (res < 0) {
+ IPAERR("ipa_get_rt_hw_tbl_size failed %d\n", res);
+ goto base_err;
+ }
+
+ mem->size = res;
mem->size -= hdr_sz;
mem->size = (mem->size + IPA_RT_TABLE_MEMORY_ALLIGNMENT) &
~IPA_RT_TABLE_MEMORY_ALLIGNMENT;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
index 67e9b397a8b4..e7e5cf114242 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
@@ -24,6 +24,17 @@
#define IPA_NAT_TEMP_MEM_SIZE 128
+enum nat_table_type {
+ IPA_NAT_BASE_TBL = 0,
+ IPA_NAT_EXPN_TBL = 1,
+ IPA_NAT_INDX_TBL = 2,
+ IPA_NAT_INDEX_EXPN_TBL = 3,
+};
+
+#define NAT_TABLE_ENTRY_SIZE_BYTE 32
+#define NAT_INTEX_TABLE_ENTRY_SIZE_BYTE 4
+
+
static int ipa3_nat_vma_fault_remap(
struct vm_area_struct *vma, struct vm_fault *vmf)
{
@@ -571,6 +582,71 @@ int ipa3_nat_dma_cmd(struct ipa_ioc_nat_dma_cmd *dma)
goto bail;
}
+ for (cnt = 0; cnt < dma->entries; cnt++) {
+ if (dma->dma[cnt].table_index >= 1) {
+ IPAERR("Invalid table index %d\n",
+ dma->dma[cnt].table_index);
+ ret = -EPERM;
+ goto bail;
+ }
+
+ switch (dma->dma[cnt].base_addr) {
+ case IPA_NAT_BASE_TBL:
+ if (dma->dma[cnt].offset >=
+ (ipa3_ctx->nat_mem.size_base_tables + 1) *
+ NAT_TABLE_ENTRY_SIZE_BYTE) {
+ IPAERR("Invalid offset %d\n",
+ dma->dma[cnt].offset);
+ ret = -EPERM;
+ goto bail;
+ }
+
+ break;
+
+ case IPA_NAT_EXPN_TBL:
+ if (dma->dma[cnt].offset >=
+ ipa3_ctx->nat_mem.size_expansion_tables *
+ NAT_TABLE_ENTRY_SIZE_BYTE) {
+ IPAERR("Invalid offset %d\n",
+ dma->dma[cnt].offset);
+ ret = -EPERM;
+ goto bail;
+ }
+
+ break;
+
+ case IPA_NAT_INDX_TBL:
+ if (dma->dma[cnt].offset >=
+ (ipa3_ctx->nat_mem.size_base_tables + 1) *
+ NAT_INTEX_TABLE_ENTRY_SIZE_BYTE) {
+ IPAERR("Invalid offset %d\n",
+ dma->dma[cnt].offset);
+ ret = -EPERM;
+ goto bail;
+ }
+
+ break;
+
+ case IPA_NAT_INDEX_EXPN_TBL:
+ if (dma->dma[cnt].offset >=
+ ipa3_ctx->nat_mem.size_expansion_tables *
+ NAT_INTEX_TABLE_ENTRY_SIZE_BYTE) {
+ IPAERR("Invalid offset %d\n",
+ dma->dma[cnt].offset);
+ ret = -EPERM;
+ goto bail;
+ }
+
+ break;
+
+ default:
+ IPAERR("Invalid base_addr %d\n",
+ dma->dma[cnt].base_addr);
+ ret = -EPERM;
+ goto bail;
+ }
+ }
+
size = sizeof(struct ipa3_desc) * NUM_OF_DESC;
desc = kzalloc(size, GFP_KERNEL);
if (desc == NULL) {
diff --git a/drivers/platform/msm/seemp_core/seemp_event_encoder.c b/drivers/platform/msm/seemp_core/seemp_event_encoder.c
index df56a84bc667..36901f5fbee7 100644
--- a/drivers/platform/msm/seemp_core/seemp_event_encoder.c
+++ b/drivers/platform/msm/seemp_core/seemp_event_encoder.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 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
@@ -48,9 +48,15 @@ static void check_param_range(char *section_eq, bool param,
void encode_seemp_params(struct seemp_logk_blk *blk)
{
- char *s = blk->payload.msg + 1;
+ struct seemp_logk_blk tmp;
+ char *s = 0;
+ char *msg_section_start = 0;
+ char *msg_section_eq = 0;
+ char *msg_s = 0;
- blk->payload.msg[BLK_MAX_MSG_SZ - 1] = 0; /* zero-terminate */
+ memcpy(tmp.payload.msg, blk->payload.msg, BLK_MAX_MSG_SZ);
+ s = tmp.payload.msg + 1;
+ tmp.payload.msg[BLK_MAX_MSG_SZ - 1] = 0; /* zero-terminate */
while (true) {
char *section_start = s;
@@ -105,8 +111,13 @@ void encode_seemp_params(struct seemp_logk_blk *blk)
}
}
- encode_seemp_section(section_start, section_eq, s, param,
- numeric, id, numeric_value);
+ msg_section_start = blk->payload.msg + (section_start -
+ tmp.payload.msg);
+ msg_section_eq = blk->payload.msg + (section_eq -
+ tmp.payload.msg);
+ msg_s = blk->payload.msg + (s - tmp.payload.msg);
+ encode_seemp_section(msg_section_start, msg_section_eq,
+ msg_s, param, numeric, id, numeric_value);
if (*s == 0)
break;
diff --git a/drivers/platform/msm/spmi/spmi-dbgfs.c b/drivers/platform/msm/spmi/spmi-dbgfs.c
index 9f248470eb7c..abab29651eae 100644
--- a/drivers/platform/msm/spmi/spmi-dbgfs.c
+++ b/drivers/platform/msm/spmi/spmi-dbgfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -74,6 +74,7 @@ struct spmi_trans {
u32 addr; /* 20-bit address: SID + PID + Register offset */
u32 offset; /* Offset of last read data */
bool raw_data; /* Set to true for raw data dump */
+ struct mutex spmi_dfs_lock; /* Prevent thread concurrency */
struct spmi_controller *ctrl;
struct spmi_log_buffer *log; /* log buffer */
};
@@ -173,6 +174,7 @@ static int spmi_dfs_open(struct spmi_ctrl_data *ctrl_data, struct file *file)
trans->addr = ctrl_data->addr;
trans->ctrl = ctrl_data->ctrl;
trans->offset = trans->addr;
+ mutex_init(&trans->spmi_dfs_lock);
file->private_data = trans;
return 0;
@@ -202,6 +204,7 @@ static int spmi_dfs_close(struct inode *inode, struct file *file)
if (trans && trans->log) {
file->private_data = NULL;
+ mutex_destroy(&trans->spmi_dfs_lock);
kfree(trans->log);
kfree(trans);
}
@@ -478,14 +481,21 @@ static ssize_t spmi_dfs_reg_write(struct file *file, const char __user *buf,
int cnt = 0;
u8 *values;
size_t ret = 0;
-
+ u32 offset;
+ char *kbuf;
struct spmi_trans *trans = file->private_data;
- u32 offset = trans->offset;
+
+ mutex_lock(&trans->spmi_dfs_lock);
+
+ trans = file->private_data;
+ offset = trans->offset;
/* Make a copy of the user data */
- char *kbuf = kmalloc(count + 1, GFP_KERNEL);
- if (!kbuf)
- return -ENOMEM;
+ kbuf = kmalloc(count + 1, GFP_KERNEL);
+ if (!kbuf) {
+ ret = -ENOMEM;
+ goto unlock_mutex;
+ }
ret = copy_from_user(kbuf, buf, count);
if (ret == count) {
@@ -522,6 +532,8 @@ static ssize_t spmi_dfs_reg_write(struct file *file, const char __user *buf,
free_buf:
kfree(kbuf);
+unlock_mutex:
+ mutex_unlock(&trans->spmi_dfs_lock);
return ret;
}
@@ -542,10 +554,13 @@ static ssize_t spmi_dfs_reg_read(struct file *file, char __user *buf,
size_t ret;
size_t len;
+ mutex_lock(&trans->spmi_dfs_lock);
/* Is the the log buffer empty */
if (log->rpos >= log->wpos) {
- if (get_log_data(trans) <= 0)
- return 0;
+ if (get_log_data(trans) <= 0) {
+ len = 0;
+ goto unlock_mutex;
+ }
}
len = min(count, log->wpos - log->rpos);
@@ -553,7 +568,8 @@ static ssize_t spmi_dfs_reg_read(struct file *file, char __user *buf,
ret = copy_to_user(buf, &log->data[log->rpos], len);
if (ret == len) {
pr_err("error copy SPMI register values to user\n");
- return -EFAULT;
+ len = -EFAULT;
+ goto unlock_mutex;
}
/* 'ret' is the number of bytes not copied */
@@ -561,6 +577,9 @@ static ssize_t spmi_dfs_reg_read(struct file *file, char __user *buf,
*ppos += len;
log->rpos += len;
+
+unlock_mutex:
+ mutex_unlock(&trans->spmi_dfs_lock);
return len;
}
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 5d16b7867d60..9873ac833147 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -305,6 +305,16 @@ config MSM_CACHE_M4M_ERP64_PANIC_ON_UE
Say 'Y' here to cause kernel panic when uncorrectable cache/M4M errors
are detected.
+config MSM_L2_IA_DEBUG
+ bool "Enable MSM L2 Indirect Access Debug"
+ depends on DEBUG_FS
+ default n
+ help
+ This option enables L2 indirect access debug
+ capability. It exposes L2 indirect access
+ debugfs interface to get/set data, address,
+ and target cpus.
+
config MSM_RPM_SMD
bool "RPM driver using SMD protocol"
help
diff --git a/drivers/soc/qcom/kryo-l2-accessors.c b/drivers/soc/qcom/kryo-l2-accessors.c
index a945f9e0ba40..1d81074d7b81 100644
--- a/drivers/soc/qcom/kryo-l2-accessors.c
+++ b/drivers/soc/qcom/kryo-l2-accessors.c
@@ -1,5 +1,5 @@
/*
- * 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
@@ -80,7 +80,7 @@ u64 get_l2_indirect_reg(u64 reg)
}
EXPORT_SYMBOL(get_l2_indirect_reg);
-#if defined(CONFIG_DEBUG_FS)
+#if defined(CONFIG_MSM_L2_IA_DEBUG)
static u32 debug_addr;
static int debug_target_cpu;
@@ -180,4 +180,4 @@ static int l2_ia_debug_init(void)
}
late_initcall(l2_ia_debug_init);
-#endif /* CONFIG_DEBUG_FS */
+#endif /* CONFIG_MSM_L2_IA_DEBUG */
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 73fc9fd4c3e8..fdf761f62320 100755
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -114,6 +114,7 @@ struct ion_client {
*/
struct ion_handle {
struct kref ref;
+ unsigned int user_ref_count;
struct ion_client *client;
struct ion_buffer *buffer;
struct rb_node node;
@@ -437,6 +438,48 @@ int ion_handle_put(struct ion_handle *handle)
return ret;
}
+/* Must hold the client lock */
+static void user_ion_handle_get(struct ion_handle *handle)
+{
+ if (handle->user_ref_count++ == 0)
+ kref_get(&handle->ref);
+}
+
+/* Must hold the client lock */
+static struct ion_handle *user_ion_handle_get_check_overflow(struct ion_handle *handle)
+{
+ if (handle->user_ref_count + 1 == 0)
+ return ERR_PTR(-EOVERFLOW);
+ user_ion_handle_get(handle);
+ return handle;
+}
+
+/* passes a kref to the user ref count.
+ * We know we're holding a kref to the object before and
+ * after this call, so no need to reverify handle. */
+static struct ion_handle *pass_to_user(struct ion_handle *handle)
+{
+ struct ion_client *client = handle->client;
+ struct ion_handle *ret;
+
+ mutex_lock(&client->lock);
+ ret = user_ion_handle_get_check_overflow(handle);
+ ion_handle_put_nolock(handle);
+ mutex_unlock(&client->lock);
+ return ret;
+}
+
+/* Must hold the client lock */
+static int user_ion_handle_put_nolock(struct ion_handle *handle)
+{
+ int ret;
+
+ if (--handle->user_ref_count == 0)
+ ret = ion_handle_put_nolock(handle);
+
+ return ret;
+}
+
static struct ion_handle *ion_handle_lookup(struct ion_client *client,
struct ion_buffer *buffer)
{
@@ -648,6 +691,25 @@ static void ion_free_nolock(struct ion_client *client, struct ion_handle *handle
ion_handle_put_nolock(handle);
}
+/* Must hold the client lock */
+static void user_ion_free_nolock(struct ion_client *client, struct ion_handle *handle)
+{
+ bool valid_handle;
+
+ BUG_ON(client != handle->client);
+
+ valid_handle = ion_handle_validate(client, handle);
+ if (!valid_handle) {
+ WARN(1, "%s: invalid handle passed to free.\n", __func__);
+ return;
+ }
+ if (handle->user_ref_count == 0) {
+ WARN(1, "%s: User does not have access!\n", __func__);
+ return;
+ }
+ user_ion_handle_put_nolock(handle);
+}
+
void ion_free(struct ion_client *client, struct ion_handle *handle)
{
BUG_ON(client != handle->client);
@@ -1513,7 +1575,7 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
data.allocation.flags, true);
if (IS_ERR(handle))
return PTR_ERR(handle);
-
+ pass_to_user(handle);
data.allocation.handle = handle->id;
cleanup_handle = handle;
@@ -1529,7 +1591,7 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
mutex_unlock(&client->lock);
return PTR_ERR(handle);
}
- ion_free_nolock(client, handle);
+ user_ion_free_nolock(client, handle);
ion_handle_put_nolock(handle);
mutex_unlock(&client->lock);
break;
@@ -1553,10 +1615,15 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
struct ion_handle *handle;
handle = ion_import_dma_buf(client, data.fd.fd);
- if (IS_ERR(handle))
+ if (IS_ERR(handle)) {
ret = PTR_ERR(handle);
- else
- data.handle.handle = handle->id;
+ } else {
+ handle = pass_to_user(handle);
+ if (IS_ERR(handle))
+ ret = PTR_ERR(handle);
+ else
+ data.handle.handle = handle->id;
+ }
break;
}
case ION_IOC_SYNC:
@@ -1588,8 +1655,10 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
if (dir & _IOC_READ) {
if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) {
if (cleanup_handle) {
- ion_free(client, cleanup_handle);
- ion_handle_put(cleanup_handle);
+ mutex_lock(&client->lock);
+ user_ion_free_nolock(client, cleanup_handle);
+ ion_handle_put_nolock(cleanup_handle);
+ mutex_unlock(&client->lock);
}
return -EFAULT;
}
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c
index a1f30c238076..27b74518aaa6 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -5459,6 +5459,13 @@ static int __iw_set_ap_genie(struct net_device *dev,
return 0;
}
+ if (wrqu->data.length > DOT11F_IE_RSN_MAX_LEN) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: WPARSN Ie input length is more than max[%d]", __func__,
+ wrqu->data.length);
+ return -EINVAL;
+ }
+
switch (genie[0])
{
case DOT11F_EID_WPA:
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_unified_api.h b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_unified_api.h
index cd9f923beca8..2912d471158f 100644
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_unified_api.h
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/COMMON/wmi_unified_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -69,7 +69,7 @@ wmi_unified_remove_work(struct wmi_unified* wmi_handle);
* @return wmi_buf_t.
*/
wmi_buf_t
-wmi_buf_alloc(wmi_unified_t wmi_handle, u_int16_t len);
+wmi_buf_alloc(wmi_unified_t wmi_handle, uint32_t len);
/**
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/ath_procfs.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/ath_procfs.c
index 7b653a1dd72c..ed0cfd69d722 100644
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/ath_procfs.c
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/HIF/ath_procfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -110,17 +110,16 @@ static ssize_t ath_procfs_diag_read(struct file *file, char __user *buf,
(A_UINT8 *)read_buffer, count);
}
+ if (rv)
+ return -EIO;
+
if(copy_to_user(buf, read_buffer, count)) {
vos_mem_free(read_buffer);
return -EFAULT;
} else
vos_mem_free(read_buffer);
- if (rv == 0) {
- return count;
- } else {
- return -EIO;
- }
+ return count;
}
static ssize_t ath_procfs_diag_write(struct file *file, const char __user *buf,
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 475b65fa6b06..f28fa6e6b470 100644
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMA/wma.c
@@ -24914,7 +24914,7 @@ static VOS_STATUS wma_enable_arp_ns_offload(tp_wma_handle wma,
WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param *cmd;
A_UINT8* buf_ptr;
wmi_buf_t buf;
- int32_t len;
+ uint32_t len;
VOS_STATUS status = VOS_STATUS_SUCCESS;
u_int8_t vdev_id;
tpSirHostOffloadReq ns_offload_req;
@@ -24948,6 +24948,11 @@ static VOS_STATUS wma_enable_arp_ns_offload(tp_wma_handle wma,
count = hostoffloadreq->num_ns_offload_count;
}
+ if (count >= SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) {
+ status = VOS_STATUS_E_INVAL;
+ goto err_vdev;
+ }
+
len = sizeof(WMI_SET_ARP_NS_OFFLOAD_CMD_fixed_param) +
WMI_TLV_HDR_SIZE + /* Add size for array of NS tuples */
WMI_MAX_NS_OFFLOADS*sizeof(WMI_NS_OFFLOAD_TUPLE) +
diff --git a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_unified.c b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_unified.c
index 2937c9bbcf2c..c987c75329f5 100644
--- a/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_unified.c
+++ b/drivers/staging/qcacld-2.0/CORE/SERVICES/WMI/wmi_unified.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -131,7 +131,7 @@ uint16_t wmi_get_max_msg_len(wmi_unified_t wmi_handle)
}
wmi_buf_t
-wmi_buf_alloc(wmi_unified_t wmi_handle, u_int16_t len)
+wmi_buf_alloc(wmi_unified_t wmi_handle, uint32_t len)
{
wmi_buf_t wmi_buf;
diff --git a/drivers/usb/gadget/function/f_mbim.c b/drivers/usb/gadget/function/f_mbim.c
index 717ee2342639..84e4ab79f687 100644
--- a/drivers/usb/gadget/function/f_mbim.c
+++ b/drivers/usb/gadget/function/f_mbim.c
@@ -1997,7 +1997,8 @@ static long mbim_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
case MBIM_EP_LOOKUP:
if (!atomic_read(&mbim->online)) {
pr_warn("usb cable is not connected\n");
- return -ENOTCONN;
+ ret = -ENOTCONN;
+ break;
}
switch (mbim->xport) {
@@ -2030,7 +2031,7 @@ static long mbim_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
default:
ret = -ENODEV;
pr_err("unknown transport\n");
- break;
+ goto fail;
}
ret = copy_to_user((void __user *)arg, &info,
@@ -2046,6 +2047,7 @@ static long mbim_ioctl(struct file *fp, unsigned cmd, unsigned long arg)
ret = -EINVAL;
}
+fail:
mbim_unlock(&mbim->ioctl_excl);
return ret;
diff --git a/drivers/video/msm/mdss/mdss_compat_utils.c b/drivers/video/msm/mdss/mdss_compat_utils.c
index a9ab5c1679e9..7159d9114864 100644
--- a/drivers/video/msm/mdss/mdss_compat_utils.c
+++ b/drivers/video/msm/mdss/mdss_compat_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
* Copyright (C) 1994 Martin Schaller
*
* 2001 - Documented with DocBook
@@ -935,6 +935,7 @@ static int __to_user_pcc_coeff_v1_7(
struct mdp_pcc_data_v1_7_32 pcc_cfg_payload32;
struct mdp_pcc_data_v1_7 pcc_cfg_payload;
+ memset(&pcc_cfg_payload32, 0, sizeof(pcc_cfg_payload32));
if (copy_from_user(&pcc_cfg_payload,
pcc_cfg->cfg_payload,
sizeof(struct mdp_pcc_data_v1_7))) {
@@ -2130,6 +2131,7 @@ static int __to_user_pa_data_v1_7(
struct mdp_pa_data_v1_7_32 pa_cfg_payload32;
struct mdp_pa_data_v1_7 pa_cfg_payload;
+ memset(&pa_cfg_payload32, 0, sizeof(pa_cfg_payload32));
if (copy_from_user(&pa_cfg_payload,
pa_v2_cfg->cfg_payload,
sizeof(pa_cfg_payload))) {
diff --git a/drivers/video/msm/mdss/mdss_debug.c b/drivers/video/msm/mdss/mdss_debug.c
index aef02ef8c3b3..1cc0c9d3b6fa 100644
--- a/drivers/video/msm/mdss/mdss_debug.c
+++ b/drivers/video/msm/mdss/mdss_debug.c
@@ -81,7 +81,7 @@ static ssize_t panel_debug_base_offset_write(struct file *file,
buf[count] = 0; /* end of string */
- if (sscanf(buf, "%x %d", &off, &cnt) != 2)
+ if (sscanf(buf, "%x %u", &off, &cnt) != 2)
return -EFAULT;
if (off > dbg->max_offset)
@@ -737,11 +737,11 @@ static ssize_t mdss_debug_factor_write(struct file *file,
if (strnchr(buf, count, '/')) {
/* Parsing buf as fraction */
- if (sscanf(buf, "%d/%d", &numer, &denom) != 2)
+ if (sscanf(buf, "%u/%u", &numer, &denom) != 2)
return -EFAULT;
} else {
/* Parsing buf as percentage */
- if (sscanf(buf, "%d", &numer) != 1)
+ if (kstrtouint(buf, 0, &numer))
return -EFAULT;
denom = 100;
}
@@ -1049,7 +1049,7 @@ static ssize_t mdss_debug_perf_bw_limit_write(struct file *file,
if (strnchr(buf, count, ' ')) {
/* Parsing buf */
- if (sscanf(buf, "%d %d", &mode, &val) != 2)
+ if (sscanf(buf, "%u %u", &mode, &val) != 2)
return -EFAULT;
}
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 609479e19fa7..9931469fc87f 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -670,8 +670,8 @@ static ssize_t mdss_fb_force_panel_dead(struct device *dev,
return len;
}
- if (sscanf(buf, "%d", &pdata->panel_info.panel_force_dead) != 1)
- pr_err("sccanf buf error!\n");
+ if (kstrtouint(buf, 0, &pdata->panel_info.panel_force_dead))
+ pr_err("kstrtouint buf error!\n");
return len;
}
@@ -784,8 +784,8 @@ static ssize_t mdss_fb_change_dfps_mode(struct device *dev,
}
pinfo = &pdata->panel_info;
- if (sscanf(buf, "%d", &dfps_mode) != 1) {
- pr_err("sccanf buf error!\n");
+ if (kstrtouint(buf, 0, &dfps_mode)) {
+ pr_err("kstrtouint buf error!\n");
return len;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 52cbebd4287f..17f5a654929d 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -2445,7 +2445,7 @@ static ssize_t mdss_mdp_store_max_limit_bw(struct device *dev,
struct mdss_data_type *mdata = dev_get_drvdata(dev);
u32 data = 0;
- if (1 != sscanf(buf, "%d", &data)) {
+ if (kstrtouint(buf, 0, &data)) {
pr_info("Not able scan to bw_mode_bitmap\n");
} else {
mdata->bw_mode_bitmap = data;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index c1772b1a2507..2563b4c780e8 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -2969,7 +2969,7 @@ static ssize_t dynamic_fps_sysfs_wta_dfps(struct device *dev,
if (pdata->panel_info.dfps_update ==
DFPS_IMMEDIATE_MULTI_UPDATE_MODE_CLK_HFP) {
- if (sscanf(buf, "%d %d %d %d %d",
+ if (sscanf(buf, "%u %u %u %u %u",
&data.hfp, &data.hbp, &data.hpw,
&data.clk_rate, &data.fps) != 5) {
pr_err("could not read input\n");
@@ -3810,6 +3810,12 @@ static int mdss_mdp_hw_cursor_pipe_update(struct msm_fb_data_type *mfd,
req->transp_mask = img->bg_color & ~(0xff << var->transp.offset);
if (mfd->cursor_buf && (cursor->set & FB_CUR_SETIMAGE)) {
+ if (img->width * img->height * 4 > cursor_frame_size) {
+ pr_err("cursor image size is too large\n");
+ ret = -EINVAL;
+ goto done;
+ }
+
ret = copy_from_user(mfd->cursor_buf, img->data,
img->width * img->height * 4);
if (ret) {
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index 8482f2d11606..cc6747746440 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -320,32 +320,28 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
if (acl) {
- umode_t mode = inode->i_mode;
- retval = posix_acl_equiv_mode(acl, &mode);
- if (retval < 0)
+ struct iattr iattr;
+ struct posix_acl *old_acl = acl;
+
+ retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
+ if (retval)
goto err_out;
- else {
- struct iattr iattr;
- if (retval == 0) {
- /*
- * ACL can be represented
- * by the mode bits. So don't
- * update ACL.
- */
- acl = NULL;
- value = NULL;
- size = 0;
- }
- /* Updte the mode bits */
- iattr.ia_mode = ((mode & S_IALLUGO) |
- (inode->i_mode & ~S_IALLUGO));
- iattr.ia_valid = ATTR_MODE;
- /* FIXME should we update ctime ?
- * What is the following setxattr update the
- * mode ?
+ if (!acl) {
+ /*
+ * ACL can be represented
+ * by the mode bits. So don't
+ * update ACL.
*/
- v9fs_vfs_setattr_dotl(dentry, &iattr);
+ posix_acl_release(old_acl);
+ value = NULL;
+ size = 0;
}
+ iattr.ia_valid = ATTR_MODE;
+ /* FIXME should we update ctime ?
+ * What is the following setxattr update the
+ * mode ?
+ */
+ v9fs_vfs_setattr_dotl(dentry, &iattr);
}
break;
case ACL_TYPE_DEFAULT:
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index 9a0124a95851..fb3e64d37cb4 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -83,11 +83,9 @@ static int __btrfs_set_acl(struct btrfs_trans_handle *trans,
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
if (acl) {
- ret = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (ret < 0)
+ ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (ret)
return ret;
- if (ret == 0)
- acl = NULL;
}
ret = 0;
break;
diff --git a/fs/ceph/acl.c b/fs/ceph/acl.c
index 5bd853ba44ff..6a4a3e2a46cf 100644
--- a/fs/ceph/acl.c
+++ b/fs/ceph/acl.c
@@ -108,11 +108,9 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
if (acl) {
- ret = posix_acl_equiv_mode(acl, &new_mode);
- if (ret < 0)
+ ret = posix_acl_update_mode(inode, &new_mode, &acl);
+ if (ret)
goto out;
- if (ret == 0)
- acl = NULL;
}
break;
case ACL_TYPE_DEFAULT:
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 27695e6f4e46..d6aeb84e90b6 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -193,15 +193,11 @@ ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
case ACL_TYPE_ACCESS:
name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (error < 0)
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (error)
return error;
- else {
- inode->i_ctime = CURRENT_TIME_SEC;
- mark_inode_dirty(inode);
- if (error == 0)
- acl = NULL;
- }
+ inode->i_ctime = CURRENT_TIME_SEC;
+ mark_inode_dirty(inode);
}
break;
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index 8bbaf5bcf982..c4509495a104 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -195,15 +195,11 @@ __ext3_set_acl(handle_t *handle, struct inode *inode, int type,
case ACL_TYPE_ACCESS:
name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (error < 0)
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (error)
return error;
- else {
- inode->i_ctime = CURRENT_TIME_SEC;
- ext3_mark_inode_dirty(handle, inode);
- if (error == 0)
- acl = NULL;
- }
+ inode->i_ctime = CURRENT_TIME_SEC;
+ ext3_mark_inode_dirty(handle, inode);
}
break;
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index d40c8dbbb0d6..87d9bbf6a53f 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -201,15 +201,11 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type,
case ACL_TYPE_ACCESS:
name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (error < 0)
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (error)
return error;
- else {
- inode->i_ctime = ext4_current_time(inode);
- ext4_mark_inode_dirty(handle, inode);
- if (error == 0)
- acl = NULL;
- }
+ inode->i_ctime = ext4_current_time(inode);
+ ext4_mark_inode_dirty(handle, inode);
}
break;
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
index 83b9b5a8d112..f12d5c5ecc31 100644
--- a/fs/f2fs/acl.c
+++ b/fs/f2fs/acl.c
@@ -207,12 +207,10 @@ static int __f2fs_set_acl(struct inode *inode, int type,
case ACL_TYPE_ACCESS:
name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (error < 0)
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (error)
return error;
set_acl_inode(fi, inode->i_mode);
- if (error == 0)
- acl = NULL;
}
break;
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
index 7b3143064af1..88e66aa516c4 100644
--- a/fs/gfs2/acl.c
+++ b/fs/gfs2/acl.c
@@ -79,17 +79,11 @@ int gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
if (type == ACL_TYPE_ACCESS) {
umode_t mode = inode->i_mode;
- error = posix_acl_equiv_mode(acl, &mode);
- if (error < 0)
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (error)
return error;
-
- if (error == 0)
- acl = NULL;
-
- if (mode != inode->i_mode) {
- inode->i_mode = mode;
+ if (mode != inode->i_mode)
mark_inode_dirty(inode);
- }
}
if (acl) {
diff --git a/fs/hfsplus/posix_acl.c b/fs/hfsplus/posix_acl.c
index df0c9af68d05..71b3087b7e32 100644
--- a/fs/hfsplus/posix_acl.c
+++ b/fs/hfsplus/posix_acl.c
@@ -68,8 +68,8 @@ int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
case ACL_TYPE_ACCESS:
xattr_name = POSIX_ACL_XATTR_ACCESS;
if (acl) {
- err = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (err < 0)
+ err = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (err)
return err;
}
err = 0;
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
index 2f7a3c090489..f9f86f87d32b 100644
--- a/fs/jffs2/acl.c
+++ b/fs/jffs2/acl.c
@@ -235,9 +235,10 @@ int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
case ACL_TYPE_ACCESS:
xprefix = JFFS2_XPREFIX_ACL_ACCESS;
if (acl) {
- umode_t mode = inode->i_mode;
- rc = posix_acl_equiv_mode(acl, &mode);
- if (rc < 0)
+ umode_t mode;
+
+ rc = posix_acl_update_mode(inode, &mode, &acl);
+ if (rc)
return rc;
if (inode->i_mode != mode) {
struct iattr attr;
@@ -249,8 +250,6 @@ int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
if (rc < 0)
return rc;
}
- if (rc == 0)
- acl = NULL;
}
break;
case ACL_TYPE_DEFAULT:
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index 0c8ca830b113..9fad9f4fe883 100644
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -84,13 +84,11 @@ static int __jfs_set_acl(tid_t tid, struct inode *inode, int type,
case ACL_TYPE_ACCESS:
ea_name = POSIX_ACL_XATTR_ACCESS;
if (acl) {
- rc = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (rc < 0)
+ rc = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (rc)
return rc;
inode->i_ctime = CURRENT_TIME;
mark_inode_dirty(inode);
- if (rc == 0)
- acl = NULL;
}
break;
case ACL_TYPE_DEFAULT:
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
index 7e8282dcea2a..b6c86fe1b187 100644
--- a/fs/ocfs2/acl.c
+++ b/fs/ocfs2/acl.c
@@ -242,19 +242,13 @@ int ocfs2_set_acl(handle_t *handle,
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
umode_t mode = inode->i_mode;
- ret = posix_acl_equiv_mode(acl, &mode);
- if (ret < 0)
+ ret = posix_acl_update_mode(inode, &mode, &acl);
+ if (ret)
+ return ret;
+ ret = ocfs2_acl_set_mode(inode, di_bh,
+ handle, mode);
+ if (ret)
return ret;
- else {
- if (ret == 0)
- acl = NULL;
-
- ret = ocfs2_acl_set_mode(inode, di_bh,
- handle, mode);
- if (ret)
- return ret;
-
- }
}
break;
case ACL_TYPE_DEFAULT:
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 0855f772cd41..73aad912314e 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -594,6 +594,37 @@ no_acl:
}
EXPORT_SYMBOL_GPL(posix_acl_create);
+/**
+ * posix_acl_update_mode - update mode in set_acl
+ *
+ * Update the file mode when setting an ACL: compute the new file permission
+ * bits based on the ACL. In addition, if the ACL is equivalent to the new
+ * file mode, set *acl to NULL to indicate that no ACL should be set.
+ *
+ * As with chmod, clear the setgit bit if the caller is not in the owning group
+ * or capable of CAP_FSETID (see inode_change_ok).
+ *
+ * Called from set_acl inode operations.
+ */
+int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,
+ struct posix_acl **acl)
+{
+ umode_t mode = inode->i_mode;
+ int error;
+
+ error = posix_acl_equiv_mode(*acl, &mode);
+ if (error < 0)
+ return error;
+ if (error == 0)
+ *acl = NULL;
+ if (!in_group_p(inode->i_gid) &&
+ !capable_wrt_inode_uidgid(inode, CAP_FSETID))
+ mode &= ~S_ISGID;
+ *mode_p = mode;
+ return 0;
+}
+EXPORT_SYMBOL(posix_acl_update_mode);
+
/*
* Fix up the uids and gids in posix acl extended attributes in place.
*/
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index 4b34b9dc03dd..9b1824f35501 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -246,13 +246,9 @@ __reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
if (acl) {
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (error < 0)
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (error)
return error;
- else {
- if (error == 0)
- acl = NULL;
- }
}
break;
case ACL_TYPE_DEFAULT:
diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c
index a6522286d731..8b51a124298f 100644
--- a/fs/sdcardfs/main.c
+++ b/fs/sdcardfs/main.c
@@ -223,6 +223,13 @@ static int sdcardfs_read_super(struct super_block *sb, const char *dev_name,
atomic_inc(&lower_sb->s_active);
sdcardfs_set_lower_super(sb, lower_sb);
+ sb->s_stack_depth = lower_sb->s_stack_depth + 1;
+ if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
+ pr_err("sdcardfs: maximum fs stacking depth exceeded\n");
+ err = -EINVAL;
+ goto out_sput;
+ }
+
/* inherit maxbytes from lower file system */
sb->s_maxbytes = lower_sb->s_maxbytes;
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index a65fa5dde6e9..e0406717edbc 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -286,16 +286,11 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
return error;
if (type == ACL_TYPE_ACCESS) {
- umode_t mode = inode->i_mode;
- error = posix_acl_equiv_mode(acl, &mode);
-
- if (error <= 0) {
- acl = NULL;
-
- if (error < 0)
- return error;
- }
+ umode_t mode;
+ error = posix_acl_update_mode(inode, &mode, &acl);
+ if (error)
+ return error;
error = xfs_set_mode(inode, mode);
if (error)
return error;
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
index 3e96a6a76103..d1a8ad7e5ae4 100644
--- a/include/linux/posix_acl.h
+++ b/include/linux/posix_acl.h
@@ -95,6 +95,7 @@ extern int set_posix_acl(struct inode *, int, struct posix_acl *);
extern int posix_acl_chmod(struct inode *, umode_t);
extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **,
struct posix_acl **);
+extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **);
extern int simple_set_acl(struct inode *, struct posix_acl *, int);
extern int simple_acl_create(struct inode *, struct inode *);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index c621c6fc6e80..a7716ce4c477 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1258,6 +1258,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
int peeked, off = 0;
int err;
int is_udplite = IS_UDPLITE(sk);
+ bool checksum_valid = false;
bool slow;
if (flags & MSG_ERRQUEUE)
@@ -1283,11 +1284,12 @@ try_again:
*/
if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
- if (udp_lib_checksum_complete(skb))
+ checksum_valid = !udp_lib_checksum_complete(skb);
+ if (!checksum_valid)
goto csum_copy_err;
}
- if (skb_csum_unnecessary(skb))
+ if (checksum_valid || skb_csum_unnecessary(skb))
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
msg->msg_iov, copied);
else {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index e4a05fa60130..f167e4526418 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -388,6 +388,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
int peeked, off = 0;
int err;
int is_udplite = IS_UDPLITE(sk);
+ bool checksum_valid = false;
int is_udp4;
bool slow;
@@ -419,11 +420,12 @@ try_again:
*/
if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
- if (udp_lib_checksum_complete(skb))
+ checksum_valid = !udp_lib_checksum_complete(skb);
+ if (!checksum_valid)
goto csum_copy_err;
}
- if (skb_csum_unnecessary(skb))
+ if (checksum_valid || skb_csum_unnecessary(skb))
err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
msg->msg_iov, copied);
else {
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
index 12d6d9d1e57c..c48027724ba0 100755
--- a/sound/soc/codecs/wcd9335.c
+++ b/sound/soc/codecs/wcd9335.c
@@ -7499,6 +7499,13 @@ static int tasha_mad_input_put(struct snd_kcontrol *kcontrol,
tasha_mad_input = ucontrol->value.integer.value[0];
+ if (tasha_mad_input >= ARRAY_SIZE(tasha_conn_mad_text)) {
+ dev_err(codec->dev,
+ "%s: tasha_mad_input = %d out of bounds\n",
+ __func__, tasha_mad_input);
+ return -EINVAL;
+ }
+
if (!strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED1") ||
!strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED2") ||
!strcmp(tasha_conn_mad_text[tasha_mad_input], "NOTUSED3") ||
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 97c914ac35a4..adbeb77bcb91 100755..100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -2272,6 +2272,11 @@ static int msm_routing_ec_ref_rx_put(struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_update *update = NULL;
int valid_port = true;
+ if (mux >= e->items) {
+ pr_err("%s: Invalid mux value %d\n", __func__, mux);
+ return -EINVAL;
+ }
+
mutex_lock(&routing_lock);
switch (ucontrol->value.integer.value[0]) {
case 0:
@@ -2439,6 +2444,11 @@ static int msm_routing_ext_ec_put(struct snd_kcontrol *kcontrol,
uint16_t ext_ec_ref_port_id;
struct snd_soc_dapm_update *update = NULL;
+ if (mux >= e->items) {
+ pr_err("%s: Invalid mux value %d\n", __func__, mux);
+ return -EINVAL;
+ }
+
mutex_lock(&routing_lock);
msm_route_ext_ec_ref = ucontrol->value.integer.value[0];