From: Wenwen Wang wenwen@cs.uga.edu
[ Upstream commit 2c231c0c1dec42192aca0f87f2dc68b8f0cbc7d2 ]
In ti_dra7_xbar_probe(), 'rsv_events' is allocated through kcalloc(). Then of_property_read_u32_array() is invoked to search for the property. However, if this process fails, 'rsv_events' is not deallocated, leading to a memory leak bug. To fix this issue, free 'rsv_events' before returning the error.
Signed-off-by: Wenwen Wang wenwen@cs.uga.edu Acked-by: Peter Ujfalusi peter.ujfalusi@ti.com Link: https://lore.kernel.org/r/1565938136-7249-1-git-send-email-wenwen@cs.uga.edu Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/ti-dma-crossbar.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c index 9272b173c7465..6574cb5a12fee 100644 --- a/drivers/dma/ti-dma-crossbar.c +++ b/drivers/dma/ti-dma-crossbar.c @@ -395,8 +395,10 @@ static int ti_dra7_xbar_probe(struct platform_device *pdev)
ret = of_property_read_u32_array(node, pname, (u32 *)rsv_events, nelm * 2); - if (ret) + if (ret) { + kfree(rsv_events); return ret; + }
for (i = 0; i < nelm; i++) { ti_dra7_xbar_reserve(rsv_events[i][0], rsv_events[i][1],
From: Wenwen Wang wenwen@cs.uga.edu
[ Upstream commit 962411b05a6d3342aa649e39cda1704c1fc042c6 ]
If devm_request_irq() fails to disable all interrupts, no cleanup is performed before retuning the error. To fix this issue, invoke omap_dma_free() to do the cleanup.
Signed-off-by: Wenwen Wang wenwen@cs.uga.edu Acked-by: Peter Ujfalusi peter.ujfalusi@ti.com Link: https://lore.kernel.org/r/1565938570-7528-1-git-send-email-wenwen@cs.uga.edu Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/omap-dma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 8c1665c8fe33a..14b560facf779 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -1534,8 +1534,10 @@ static int omap_dma_probe(struct platform_device *pdev)
rc = devm_request_irq(&pdev->dev, irq, omap_dma_irq, IRQF_SHARED, "omap-dma-engine", od); - if (rc) + if (rc) { + omap_dma_free(od); return rc; + } }
if (omap_dma_glbl_read(od, CAPS_0) & CAPS_0_SUPPORT_LL123)
From: Peter Zijlstra peterz@infradead.org
[ Upstream commit 9b8bd476e78e89c9ea26c3b435ad0201c3d7dbf5 ]
Identical to __put_user(); the __get_user() argument evalution will too leak UBSAN crud into the __uaccess_begin() / __uaccess_end() region. While uncommon this was observed to happen for:
drivers/xen/gntdev.c: if (__get_user(old_status, batch->status[i]))
where UBSAN added array bound checking.
This complements commit:
6ae865615fc4 ("x86/uaccess: Dont leak the AC flag into __put_user() argument evaluation")
Tested-by Sedat Dilek sedat.dilek@gmail.com Reported-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Josh Poimboeuf jpoimboe@redhat.com Reviewed-by: Thomas Gleixner tglx@linutronix.de Cc: broonie@kernel.org Cc: sfr@canb.auug.org.au Cc: akpm@linux-foundation.org Cc: Randy Dunlap rdunlap@infradead.org Cc: mhocko@suse.cz Cc: Josh Poimboeuf jpoimboe@redhat.com Link: https://lkml.kernel.org/r/20190829082445.GM2369@hirez.programming.kicks-ass.... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/uaccess.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h index 4111edb3188e2..9718303410614 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -451,8 +451,10 @@ do { \ ({ \ int __gu_err; \ __inttype(*(ptr)) __gu_val; \ + __typeof__(ptr) __gu_ptr = (ptr); \ + __typeof__(size) __gu_size = (size); \ __uaccess_begin_nospec(); \ - __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \ + __get_user_size(__gu_val, __gu_ptr, __gu_size, __gu_err, -EFAULT); \ __uaccess_end(); \ (x) = (__force __typeof__(*(ptr)))__gu_val; \ __builtin_expect(__gu_err, 0); \
From: Tianyu Lan Tianyu.Lan@microsoft.com
[ Upstream commit 4030b4c585c41eeefec7bd20ce3d0e100a0f2e4d ]
When the 'start' parameter is >= 0xFF000000 on 32-bit systems, or >= 0xFFFFFFFF'FF000000 on 64-bit systems, fill_gva_list() gets into an infinite loop.
With such inputs, 'cur' overflows after adding HV_TLB_FLUSH_UNIT and always compares as less than end. Memory is filled with guest virtual addresses until the system crashes.
Fix this by never incrementing 'cur' to be larger than 'end'.
Reported-by: Jong Hyun Park park.jonghyun@yonsei.ac.kr Signed-off-by: Tianyu Lan Tianyu.Lan@microsoft.com Reviewed-by: Michael Kelley mikelley@microsoft.com Cc: Borislav Petkov bp@alien8.de Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Peter Zijlstra peterz@infradead.org Cc: Thomas Gleixner tglx@linutronix.de Fixes: 2ffd9e33ce4a ("x86/hyper-v: Use hypercall for remote TLB flush") Signed-off-by: Ingo Molnar mingo@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/hyperv/mmu.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/x86/hyperv/mmu.c b/arch/x86/hyperv/mmu.c index 56c9ebac946fe..47718fff0b797 100644 --- a/arch/x86/hyperv/mmu.c +++ b/arch/x86/hyperv/mmu.c @@ -57,12 +57,14 @@ static inline int fill_gva_list(u64 gva_list[], int offset, * Lower 12 bits encode the number of additional * pages to flush (in addition to the 'cur' page). */ - if (diff >= HV_TLB_FLUSH_UNIT) + if (diff >= HV_TLB_FLUSH_UNIT) { gva_list[gva_n] |= ~PAGE_MASK; - else if (diff) + cur += HV_TLB_FLUSH_UNIT; + } else if (diff) { gva_list[gva_n] |= (diff - 1) >> PAGE_SHIFT; + cur = end; + }
- cur += HV_TLB_FLUSH_UNIT; gva_n++;
} while (cur < end);
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit f19e4ed1e1edbfa3c9ccb9fed17759b7d6db24c6 ]
revert cc57c07343bd "configfs: fix registered group removal" It was an attempt to handle something that fundamentally doesn't work - configfs_register_group() should never be done in a part of tree that can be rmdir'ed. And in mainline it never had been, so let's not borrow trouble; the fix was racy anyway, it would take a lot more to make that work and desired semantics is not clear.
Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- fs/configfs/dir.c | 11 ----------- 1 file changed, 11 deletions(-)
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index a1985a9ad2d64..64fdb12e6ad61 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -1782,16 +1782,6 @@ void configfs_unregister_group(struct config_group *group) struct dentry *dentry = group->cg_item.ci_dentry; struct dentry *parent = group->cg_item.ci_parent->ci_dentry;
- mutex_lock(&subsys->su_mutex); - if (!group->cg_item.ci_parent->ci_group) { - /* - * The parent has already been unlinked and detached - * due to a rmdir. - */ - goto unlink_group; - } - mutex_unlock(&subsys->su_mutex); - inode_lock_nested(d_inode(parent), I_MUTEX_PARENT); spin_lock(&configfs_dirent_lock); configfs_detach_prep(dentry, NULL); @@ -1806,7 +1796,6 @@ void configfs_unregister_group(struct config_group *group) dput(dentry);
mutex_lock(&subsys->su_mutex); -unlink_group: unlink_group(group); mutex_unlock(&subsys->su_mutex); }
From: Hillf Danton hdanton@sina.com
[ Upstream commit d41a3effbb53b1bcea41e328d16a4d046a508381 ]
If a request_key authentication token key gets revoked, there's a window in which request_key_auth_describe() can see it with a NULL payload - but it makes no check for this and something like the following oops may occur:
BUG: Kernel NULL pointer dereference at 0x00000038 Faulting instruction address: 0xc0000000004ddf30 Oops: Kernel access of bad area, sig: 11 [#1] ... NIP [...] request_key_auth_describe+0x90/0xd0 LR [...] request_key_auth_describe+0x54/0xd0 Call Trace: [...] request_key_auth_describe+0x54/0xd0 (unreliable) [...] proc_keys_show+0x308/0x4c0 [...] seq_read+0x3d0/0x540 [...] proc_reg_read+0x90/0x110 [...] __vfs_read+0x3c/0x70 [...] vfs_read+0xb4/0x1b0 [...] ksys_read+0x7c/0x130 [...] system_call+0x5c/0x70
Fix this by checking for a NULL pointer when describing such a key.
Also make the read routine check for a NULL pointer to be on the safe side.
[DH: Modified to not take already-held rcu lock and modified to also check in the read routine]
Fixes: 04c567d9313e ("[PATCH] Keys: Fix race between two instantiators of a key") Reported-by: Sachin Sant sachinp@linux.vnet.ibm.com Signed-off-by: Hillf Danton hdanton@sina.com Signed-off-by: David Howells dhowells@redhat.com Tested-by: Sachin Sant sachinp@linux.vnet.ibm.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- security/keys/request_key_auth.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 5e515791ccd11..1d34b2a5f485e 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c @@ -71,6 +71,9 @@ static void request_key_auth_describe(const struct key *key, { struct request_key_auth *rka = get_request_key_auth(key);
+ if (!rka) + return; + seq_puts(m, "key:"); seq_puts(m, key->description); if (key_is_positive(key)) @@ -88,6 +91,9 @@ static long request_key_auth_read(const struct key *key, size_t datalen; long ret;
+ if (!rka) + return -EKEYREVOKED; + datalen = rka->callout_len; ret = datalen;
From: Stuart Hayes stuart.w.hayes@gmail.com
[ Upstream commit 36b7200f67dfe75b416b5281ed4ace9927b513bc ]
When devices are attached to the amd_iommu in a kdump kernel, the old device table entries (DTEs), which were copied from the crashed kernel, will be overwritten with a new domain number. When the new DTE is written, the IOMMU is told to flush the DTE from its internal cache--but it is not told to flush the translation cache entries for the old domain number.
Without this patch, AMD systems using the tg3 network driver fail when kdump tries to save the vmcore to a network system, showing network timeouts and (sometimes) IOMMU errors in the kernel log.
This patch will flush IOMMU translation cache entries for the old domain when a DTE gets overwritten with a new domain number.
Signed-off-by: Stuart Hayes stuart.w.hayes@gmail.com Fixes: 3ac3e5ee5ed5 ('iommu/amd: Copy old trans table from old kernel') Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/amd_iommu.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 684f7cdd814b6..822c85226a29f 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -1150,6 +1150,17 @@ static void amd_iommu_flush_tlb_all(struct amd_iommu *iommu) iommu_completion_wait(iommu); }
+static void amd_iommu_flush_tlb_domid(struct amd_iommu *iommu, u32 dom_id) +{ + struct iommu_cmd cmd; + + build_inv_iommu_pages(&cmd, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, + dom_id, 1); + iommu_queue_command(iommu, &cmd); + + iommu_completion_wait(iommu); +} + static void amd_iommu_flush_all(struct amd_iommu *iommu) { struct iommu_cmd cmd; @@ -1835,6 +1846,7 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats) { u64 pte_root = 0; u64 flags = 0; + u32 old_domid;
if (domain->mode != PAGE_MODE_NONE) pte_root = iommu_virt_to_phys(domain->pt_root); @@ -1877,8 +1889,20 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats) flags &= ~DEV_DOMID_MASK; flags |= domain->id;
+ old_domid = amd_iommu_dev_table[devid].data[1] & DEV_DOMID_MASK; amd_iommu_dev_table[devid].data[1] = flags; amd_iommu_dev_table[devid].data[0] = pte_root; + + /* + * A kdump kernel might be replacing a domain ID that was copied from + * the previous kernel--if so, it needs to flush the translation cache + * entries for the old domain ID that is being overwritten + */ + if (old_domid) { + struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; + + amd_iommu_flush_tlb_domid(iommu, old_domid); + } }
static void clear_dte_entry(u16 devid)
From: Joerg Roedel jroedel@suse.de
[ Upstream commit 754265bcab78a9014f0f99cd35e0d610fcd7dfa7 ]
After the conversion to lock-less dma-api call the increase_address_space() function can be called without any locking. Multiple CPUs could potentially race for increasing the address space, leading to invalid domain->mode settings and invalid page-tables. This has been happening in the wild under high IO load and memory pressure.
Fix the race by locking this operation. The function is called infrequently so that this does not introduce a performance regression in the dma-api path again.
Reported-by: Qian Cai cai@lca.pw Fixes: 256e4621c21a ('iommu/amd: Make use of the generic IOVA allocator') Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/amd_iommu.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 822c85226a29f..a1174e61daf4e 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -1337,18 +1337,21 @@ static void domain_flush_devices(struct protection_domain *domain) * another level increases the size of the address space by 9 bits to a size up * to 64 bits. */ -static bool increase_address_space(struct protection_domain *domain, +static void increase_address_space(struct protection_domain *domain, gfp_t gfp) { + unsigned long flags; u64 *pte;
- if (domain->mode == PAGE_MODE_6_LEVEL) + spin_lock_irqsave(&domain->lock, flags); + + if (WARN_ON_ONCE(domain->mode == PAGE_MODE_6_LEVEL)) /* address space already 64 bit large */ - return false; + goto out;
pte = (void *)get_zeroed_page(gfp); if (!pte) - return false; + goto out;
*pte = PM_LEVEL_PDE(domain->mode, iommu_virt_to_phys(domain->pt_root)); @@ -1356,7 +1359,10 @@ static bool increase_address_space(struct protection_domain *domain, domain->mode += 1; domain->updated = true;
- return true; +out: + spin_unlock_irqrestore(&domain->lock, flags); + + return; }
static u64 *alloc_pte(struct protection_domain *domain,
linux-stable-mirror@lists.linaro.org