The patch titled
Subject: fs/binfmt_elf.c: allocate initialized memory in fill_thread_core_info()
has been added to the -mm tree. Its filename is
fs-binfmt_elfc-allocate-initialized-memory-in-fill_thread_core_info.patch
This patch should soon appear at
http://ozlabs.org/~akpm/mmots/broken-out/fs-binfmt_elfc-allocate-initialize…
and later at
http://ozlabs.org/~akpm/mmotm/broken-out/fs-binfmt_elfc-allocate-initialize…
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next and is updated
there every 3-4 working days
------------------------------------------------------
From: Alexander Potapenko <glider(a)google.com>
Subject: fs/binfmt_elf.c: allocate initialized memory in fill_thread_core_info()
KMSAN reported uninitialized data being written to disk when dumping core.
As a result, several kilobytes of kmalloc memory may be written to the
core file and then read by a non-privileged user.
Link: http://lkml.kernel.org/r/20200419100848.63472-1-glider@google.com
Link: https://github.com/google/kmsan/issues/76
Signed-off-by: Alexander Potapenko <glider(a)google.com>
Reported-by: sam <sunhaoyl(a)outlook.com>
Cc: Alexey Dobriyan <adobriyan(a)gmail.com>
Cc: Kees Cook <keescook(a)chromium.org>
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
---
fs/binfmt_elf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/binfmt_elf.c~fs-binfmt_elfc-allocate-initialized-memory-in-fill_thread_core_info
+++ a/fs/binfmt_elf.c
@@ -1733,7 +1733,7 @@ static int fill_thread_core_info(struct
(!regset->active || regset->active(t->task, regset) > 0)) {
int ret;
size_t size = regset_size(t->task, regset);
- void *data = kmalloc(size, GFP_KERNEL);
+ void *data = kzalloc(size, GFP_KERNEL);
if (unlikely(!data))
return 0;
ret = regset->get(t->task, regset,
_
Patches currently in -mm which might be from glider(a)google.com are
fs-binfmt_elfc-allocate-initialized-memory-in-fill_thread_core_info.patch
Today it can happen that an event channel is being removed from the
system while the event handling loop is active. This can lead to a
race resulting in crashes or WARN() splats.
Fix this problem by using a rwlock taken as reader in the event
handling loop and as writer when removing an event channel.
As the observed problem was a NULL dereference in evtchn_from_irq()
make this function more robust against races by testing the irq_info
pointer to be not NULL before dereferencing it.
Cc: Marek Marczykowski-Górecki <marmarek(a)invisiblethingslab.com>
Cc: stable(a)vger.kernel.org
Reported-by: Marek Marczykowski-Górecki <marmarek(a)invisiblethingslab.com>
Signed-off-by: Juergen Gross <jgross(a)suse.com>
---
drivers/xen/events/events_base.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
index 3a791c8485d0..178a471906de 100644
--- a/drivers/xen/events/events_base.c
+++ b/drivers/xen/events/events_base.c
@@ -33,6 +33,7 @@
#include <linux/slab.h>
#include <linux/irqnr.h>
#include <linux/pci.h>
+#include <linux/spinlock.h>
#ifdef CONFIG_X86
#include <asm/desc.h>
@@ -70,6 +71,9 @@ const struct evtchn_ops *evtchn_ops;
*/
static DEFINE_MUTEX(irq_mapping_update_lock);
+/* Lock protecting event handling loop against removing event channels. */
+static DEFINE_RWLOCK(evtchn_rwlock);
+
static LIST_HEAD(xen_irq_list_head);
/* IRQ <-> VIRQ mapping. */
@@ -247,10 +251,14 @@ static void xen_irq_info_cleanup(struct irq_info *info)
*/
evtchn_port_t evtchn_from_irq(unsigned irq)
{
- if (WARN(irq >= nr_irqs, "Invalid irq %d!\n", irq))
+ struct irq_info *info = NULL;
+
+ if (likely(irq < nr_irqs))
+ info = info_for_irq(irq);
+ if (WARN(!info, "Invalid irq %d!\n", irq))
return 0;
- return info_for_irq(irq)->evtchn;
+ return info->evtchn;
}
unsigned int irq_from_evtchn(evtchn_port_t evtchn)
@@ -603,6 +611,7 @@ static void __unbind_from_irq(unsigned int irq)
{
evtchn_port_t evtchn = evtchn_from_irq(irq);
struct irq_info *info = irq_get_handler_data(irq);
+ unsigned long flags;
if (info->refcnt > 0) {
info->refcnt--;
@@ -610,8 +619,10 @@ static void __unbind_from_irq(unsigned int irq)
return;
}
+ write_lock_irqsave(&evtchn_rwlock, flags);
+
if (VALID_EVTCHN(evtchn)) {
- unsigned int cpu = cpu_from_irq(irq);
+ unsigned int cpu = cpu_from_irq(irq);;
xen_evtchn_close(evtchn);
@@ -629,6 +640,8 @@ static void __unbind_from_irq(unsigned int irq)
xen_irq_info_cleanup(info);
}
+ write_unlock_irqrestore(&evtchn_rwlock, flags);
+
xen_free_irq(irq);
}
@@ -1219,6 +1232,8 @@ static void __xen_evtchn_do_upcall(void)
struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
int cpu = smp_processor_id();
+ read_lock(&evtchn_rwlock);
+
do {
vcpu_info->evtchn_upcall_pending = 0;
@@ -1229,6 +1244,8 @@ static void __xen_evtchn_do_upcall(void)
virt_rmb(); /* Hypervisor can set upcall pending. */
} while (vcpu_info->evtchn_upcall_pending);
+
+ read_unlock(&evtchn_rwlock);
}
void xen_evtchn_do_upcall(struct pt_regs *regs)
--
2.16.4