diff options
author | Wilson Sung <wilsonsung@google.com> | 2019-07-12 11:57:53 +0800 |
---|---|---|
committer | Wilson Sung <wilsonsung@google.com> | 2019-07-12 11:58:15 +0800 |
commit | 583404d31612089b413bbe166a923dcdd3d56af1 (patch) | |
tree | 3d63091c1b14adc9819bc6fc3b9610e7db88f76e | |
parent | 960f15809be0e4ef61f7517e9baad6e16ea3cc84 (diff) | |
parent | de7145ad5437bc460cb745662924408d31c15d8e (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.h | 1 | ||||
-rw-r--r-- | arch/arm64/mm/mmu.c | 33 | ||||
-rw-r--r-- | drivers/android/binder.c | 12 | ||||
-rw-r--r-- | drivers/gpu/msm/kgsl.c | 4 | ||||
-rw-r--r-- | drivers/media/platform/msm/camera/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c | 19 | ||||
-rw-r--r-- | drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c | 9 |
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; |