aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilson Sung <wilsonsung@google.com>2019-07-12 11:57:53 +0800
committerWilson Sung <wilsonsung@google.com>2019-07-12 11:58:15 +0800
commit583404d31612089b413bbe166a923dcdd3d56af1 (patch)
tree3d63091c1b14adc9819bc6fc3b9610e7db88f76e
parent960f15809be0e4ef61f7517e9baad6e16ea3cc84 (diff)
parentde7145ad5437bc460cb745662924408d31c15d8e (diff)
Merge branch 'android-msm-pixel-4.9-qt-security-next' into android-msm-pixel-4.9-qtandroid-q-preview-6_r0.6android-10.0.0_r0.4
SEP 2019.1 Bug: 136171028 Bug: 136170907 Change-Id: I4bd4bc4871e70d94e47dda2f4d4966d6a4e0e3e7 Signed-off-by: Wilson Sung <wilsonsung@google.com>
-rw-r--r--arch/arm64/include/asm/pgtable.h1
-rw-r--r--arch/arm64/mm/mmu.c33
-rw-r--r--drivers/android/binder.c12
-rw-r--r--drivers/gpu/msm/kgsl.c4
-rw-r--r--drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c19
-rw-r--r--drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c9
6 files changed, 58 insertions, 20 deletions
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 9f1bba621829..cd63d71551fe 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -386,6 +386,7 @@ static inline int pmd_protnone(pmd_t pmd)
#define pud_write(pud) pte_write(pud_pte(pud))
#define pud_pfn(pud) (((pud_val(pud) & PUD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
+#define pfn_pud(pfn,prot) (__pud(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
#define set_pmd_at(mm, addr, pmdp, pmd) set_pte_at(mm, addr, (pte_t *)pmdp, pmd_pte(pmd))
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 9e2ec8ae6e99..04ca1d4ffc3c 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -135,6 +135,17 @@ static phys_addr_t __init early_pgtable_alloc(void)
return phys;
}
+static bool pgattr_change_is_safe(u64 old, u64 new)
+{
+ /*
+ * The following mapping attributes may be updated in live
+ * kernel mappings without the need for break-before-make.
+ */
+ static const pteval_t mask = PTE_PXN | PTE_RDONLY | PTE_WRITE;
+
+ return old == 0 || new == 0 || ((old ^ new) & ~mask) == 0;
+}
+
static void alloc_init_pte(pmd_t *pmd, unsigned long addr,
unsigned long end, unsigned long pfn,
pgprot_t prot,
@@ -826,23 +837,33 @@ int __init arch_ioremap_pmd_supported(void)
int pud_set_huge(pud_t *pud, phys_addr_t phys, pgprot_t prot)
{
- /* ioremap_page_range doesn't honour BBM */
- if (pud_present(READ_ONCE(*pud)))
+ pgprot_t sect_prot = __pgprot(PUD_TYPE_SECT |
+ pgprot_val(mk_sect_prot(prot)));
+ pud_t new_pud = pfn_pud(__phys_to_pfn(phys), sect_prot);
+
+ /* Only allow permission changes for now */
+ if (!pgattr_change_is_safe(READ_ONCE(pud_val(*pud)),
+ pud_val(new_pud)))
return 0;
BUG_ON(phys & ~PUD_MASK);
- set_pud(pud, __pud(phys | PUD_TYPE_SECT | pgprot_val(mk_sect_prot(prot))));
+ set_pud(pud, new_pud);
return 1;
}
int pmd_set_huge(pmd_t *pmd, phys_addr_t phys, pgprot_t prot)
{
- /* ioremap_page_range doesn't honour BBM */
- if (pmd_present(READ_ONCE(*pmd)))
+ pgprot_t sect_prot = __pgprot(PMD_TYPE_SECT |
+ pgprot_val(mk_sect_prot(prot)));
+ pmd_t new_pmd = pfn_pmd(__phys_to_pfn(phys), sect_prot);
+
+ /* Only allow permission changes for now */
+ if (!pgattr_change_is_safe(READ_ONCE(pmd_val(*pmd)),
+ pmd_val(new_pmd)))
return 0;
BUG_ON(phys & ~PMD_MASK);
- set_pmd(pmd, __pmd(phys | PMD_TYPE_SECT | pgprot_val(mk_sect_prot(prot))));
+ set_pmd(pmd, new_pmd);
return 1;
}
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index e9043be7d1fc..187eb124acdf 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -3277,6 +3277,7 @@ static void binder_transaction(struct binder_proc *proc,
if (target_node && target_node->txn_security_ctx) {
u32 secid;
+ size_t added_size;
security_task_getsecid(proc->tsk, &secid);
ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
@@ -3286,7 +3287,15 @@ static void binder_transaction(struct binder_proc *proc,
return_error_line = __LINE__;
goto err_get_secctx_failed;
}
- extra_buffers_size += ALIGN(secctx_sz, sizeof(u64));
+ added_size = ALIGN(secctx_sz, sizeof(u64));
+ extra_buffers_size += added_size;
+ if (extra_buffers_size < added_size) {
+ /* integer overflow of extra_buffers_size */
+ return_error = BR_FAILED_REPLY;
+ return_error_param = EINVAL;
+ return_error_line = __LINE__;
+ goto err_bad_extra_size;
+ }
}
trace_binder_transaction(reply, t, target_node);
@@ -3635,6 +3644,7 @@ err_copy_data_failed:
t->buffer->transaction = NULL;
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
err_binder_alloc_buf_failed:
+err_bad_extra_size:
if (secctx)
security_release_secctx(secctx, secctx_sz);
err_get_secctx_failed:
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index a2d60712ea7c..7d4b70a69f24 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2019, 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
@@ -327,7 +327,7 @@ kgsl_mem_entry_destroy(struct kref *kref)
entry->memdesc.sgt->nents, i) {
page = sg_page(sg);
for (j = 0; j < (sg->length >> PAGE_SHIFT); j++)
- set_page_dirty(nth_page(page, j));
+ set_page_dirty_lock(nth_page(page, j));
}
}
diff --git a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
index 29394e1f55c2..acae49c0d0b9 100644
--- a/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c
@@ -166,13 +166,6 @@ static int cam_lrme_mgr_util_prepare_io_buffer(int32_t iommu_hdl,
io_cfg[i].resource_type,
io_cfg[i].fence, io_cfg[i].format);
- if ((num_in_buf > io_buf_size) ||
- (num_out_buf > io_buf_size)) {
- CAM_ERR(CAM_LRME, "Invalid number of buffers %d %d %d",
- num_in_buf, num_out_buf, io_buf_size);
- return -EINVAL;
- }
-
memset(io_addr, 0, sizeof(io_addr));
for (plane = 0; plane < CAM_PACKET_MAX_PLANES; plane++) {
if (!io_cfg[i].mem_handle[plane])
@@ -200,6 +193,12 @@ static int cam_lrme_mgr_util_prepare_io_buffer(int32_t iommu_hdl,
switch (io_cfg[i].direction) {
case CAM_BUF_INPUT: {
+ if (num_in_buf >= io_buf_size) {
+ CAM_ERR(CAM_LRME,
+ "Invalid number of buffers %d %d %d",
+ num_in_buf, num_out_buf, io_buf_size);
+ return -EINVAL;
+ }
prepare->in_map_entries[num_in_buf].resource_handle =
io_cfg[i].resource_type;
prepare->in_map_entries[num_in_buf].sync_id =
@@ -215,6 +214,12 @@ static int cam_lrme_mgr_util_prepare_io_buffer(int32_t iommu_hdl,
break;
}
case CAM_BUF_OUTPUT: {
+ if (num_out_buf >= io_buf_size) {
+ CAM_ERR(CAM_LRME,
+ "Invalid number of buffers %d %d %d",
+ num_in_buf, num_out_buf, io_buf_size);
+ return -EINVAL;
+ }
prepare->out_map_entries[num_out_buf].resource_handle =
io_cfg[i].resource_type;
prepare->out_map_entries[num_out_buf].sync_id =
diff --git a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
index 9a21282531f9..f1ed1c90085a 100644
--- a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
+++ b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
@@ -1,5 +1,4 @@
-/* Copyright (c) 2011-2014, 2017-2018, The Linux Foundation.
- * All rights reserved.
+/* Copyright (c) 2011-2014, 2017-2019, 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
@@ -367,12 +366,13 @@ int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
}
} else {
for (i = num_clk - 1; i >= 0; i--) {
- if (clk_ptr[i] != NULL) {
+ if (!IS_ERR_OR_NULL(clk_ptr[i])) {
CDBG("%s disable %s\n", __func__,
clk_info[i].clk_name);
clk_disable(clk_ptr[i]);
clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
+ clk_ptr[i] = NULL;
}
}
}
@@ -386,10 +386,11 @@ cam_clk_set_err:
clk_put(clk_ptr[i]);
cam_clk_get_err:
for (i--; i >= 0; i--) {
- if (clk_ptr[i] != NULL) {
+ if (!IS_ERR_OR_NULL(clk_ptr[i])) {
clk_disable(clk_ptr[i]);
clk_unprepare(clk_ptr[i]);
clk_put(clk_ptr[i]);
+ clk_ptr[i] = NULL;
}
}
return rc;