From: Greg Kroah-Hartman Date: Mon, 12 Mar 2018 15:37:50 +0000 (+0100) Subject: 3.18-stable patches X-Git-Tag: v4.14.27~42 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e6a100554e12267f142be661c62ba1f8feffdbbe;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: alsa-seq-don-t-allow-resizing-pool-in-use.patch alsa-seq-more-protection-for-concurrent-write-and-ioctl-races.patch input-matrix_keypad-fix-race-when-disabling-interrupts.patch mips-bmips-do-not-mask-ipis-during-suspend.patch scsi-qla2xxx-fix-null-pointer-crash-due-to-active-timer-for-abts.patch x86-mce-serialize-sysfs-changes.patch --- diff --git a/queue-3.18/alsa-seq-don-t-allow-resizing-pool-in-use.patch b/queue-3.18/alsa-seq-don-t-allow-resizing-pool-in-use.patch new file mode 100644 index 00000000000..a9046ab87b0 --- /dev/null +++ b/queue-3.18/alsa-seq-don-t-allow-resizing-pool-in-use.patch @@ -0,0 +1,45 @@ +From d85739367c6d56e475c281945c68fdb05ca74b4c Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 5 Mar 2018 22:00:55 +0100 +Subject: ALSA: seq: Don't allow resizing pool in use +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Takashi Iwai + +commit d85739367c6d56e475c281945c68fdb05ca74b4c upstream. + +This is a fix for a (sort of) fallout in the recent commit +d15d662e89fc ("ALSA: seq: Fix racy pool initializations") for +CVE-2018-1000004. +As the pool resize deletes the existing cells, it may lead to a race +when another thread is writing concurrently, eventually resulting a +UAF. + +A simple workaround is not to allow the pool resizing when the pool is +in use. It's an invalid behavior in anyway. + +Fixes: d15d662e89fc ("ALSA: seq: Fix racy pool initializations") +Reported-by: 范龙飞 +Reported-by: Nicolai Stange +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/seq/seq_clientmgr.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -1929,6 +1929,9 @@ static int snd_seq_ioctl_set_client_pool + (! snd_seq_write_pool_allocated(client) || + info.output_pool != client->pool->size)) { + if (snd_seq_write_pool_allocated(client)) { ++ /* is the pool in use? */ ++ if (atomic_read(&client->pool->counter)) ++ return -EBUSY; + /* remove all existing cells */ + snd_seq_pool_mark_closing(client->pool); + snd_seq_queue_client_leave_cells(client->number); diff --git a/queue-3.18/alsa-seq-more-protection-for-concurrent-write-and-ioctl-races.patch b/queue-3.18/alsa-seq-more-protection-for-concurrent-write-and-ioctl-races.patch new file mode 100644 index 00000000000..b9e129f9bbe --- /dev/null +++ b/queue-3.18/alsa-seq-more-protection-for-concurrent-write-and-ioctl-races.patch @@ -0,0 +1,179 @@ +From 7bd80091567789f1c0cb70eb4737aac8bcd2b6b9 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 5 Mar 2018 22:06:09 +0100 +Subject: ALSA: seq: More protection for concurrent write and ioctl races +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Takashi Iwai + +commit 7bd80091567789f1c0cb70eb4737aac8bcd2b6b9 upstream. + +This patch is an attempt for further hardening against races between +the concurrent write and ioctls. The previous fix d15d662e89fc +("ALSA: seq: Fix racy pool initializations") covered the race of the +pool initialization at writer and the pool resize ioctl by the +client->ioctl_mutex (CVE-2018-1000004). However, basically this mutex +should be applied more widely to the whole write operation for +avoiding the unexpected pool operations by another thread. + +The only change outside snd_seq_write() is the additional mutex +argument to helper functions, so that we can unlock / relock the given +mutex temporarily during schedule() call for blocking write. + +Fixes: d15d662e89fc ("ALSA: seq: Fix racy pool initializations") +Reported-by: 范龙飞 +Reported-by: Nicolai Stange +Reviewed-and-tested-by: Nicolai Stange +Cc: +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/seq/seq_clientmgr.c | 18 +++++++++++------- + sound/core/seq/seq_fifo.c | 2 +- + sound/core/seq/seq_memory.c | 14 ++++++++++---- + sound/core/seq/seq_memory.h | 3 ++- + 4 files changed, 24 insertions(+), 13 deletions(-) + +--- a/sound/core/seq/seq_clientmgr.c ++++ b/sound/core/seq/seq_clientmgr.c +@@ -919,7 +919,8 @@ int snd_seq_dispatch_event(struct snd_se + static int snd_seq_client_enqueue_event(struct snd_seq_client *client, + struct snd_seq_event *event, + struct file *file, int blocking, +- int atomic, int hop) ++ int atomic, int hop, ++ struct mutex *mutexp) + { + struct snd_seq_event_cell *cell; + int err; +@@ -957,7 +958,8 @@ static int snd_seq_client_enqueue_event( + return -ENXIO; /* queue is not allocated */ + + /* allocate an event cell */ +- err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic, file); ++ err = snd_seq_event_dup(client->pool, event, &cell, !blocking || atomic, ++ file, mutexp); + if (err < 0) + return err; + +@@ -1026,12 +1028,11 @@ static ssize_t snd_seq_write(struct file + return -ENXIO; + + /* allocate the pool now if the pool is not allocated yet */ ++ mutex_lock(&client->ioctl_mutex); + if (client->pool->size > 0 && !snd_seq_write_pool_allocated(client)) { +- mutex_lock(&client->ioctl_mutex); + err = snd_seq_pool_init(client->pool); +- mutex_unlock(&client->ioctl_mutex); + if (err < 0) +- return -ENOMEM; ++ goto out; + } + + /* only process whole events */ +@@ -1082,7 +1083,7 @@ static ssize_t snd_seq_write(struct file + /* ok, enqueue it */ + err = snd_seq_client_enqueue_event(client, &event, file, + !(file->f_flags & O_NONBLOCK), +- 0, 0); ++ 0, 0, &client->ioctl_mutex); + if (err < 0) + break; + +@@ -1093,6 +1094,8 @@ static ssize_t snd_seq_write(struct file + written += len; + } + ++ out: ++ mutex_unlock(&client->ioctl_mutex); + return written ? written : err; + } + +@@ -2355,7 +2358,8 @@ static int kernel_client_enqueue(int cli + if (! cptr->accept_output) + result = -EPERM; + else /* send it */ +- result = snd_seq_client_enqueue_event(cptr, ev, file, blocking, atomic, hop); ++ result = snd_seq_client_enqueue_event(cptr, ev, file, blocking, ++ atomic, hop, NULL); + + snd_seq_client_unlock(cptr); + return result; +--- a/sound/core/seq/seq_fifo.c ++++ b/sound/core/seq/seq_fifo.c +@@ -123,7 +123,7 @@ int snd_seq_fifo_event_in(struct snd_seq + return -EINVAL; + + snd_use_lock_use(&f->use_lock); +- err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL); /* always non-blocking */ ++ err = snd_seq_event_dup(f->pool, event, &cell, 1, NULL, NULL); /* always non-blocking */ + if (err < 0) { + if ((err == -ENOMEM) || (err == -EAGAIN)) + atomic_inc(&f->overflow); +--- a/sound/core/seq/seq_memory.c ++++ b/sound/core/seq/seq_memory.c +@@ -221,7 +221,8 @@ void snd_seq_cell_free(struct snd_seq_ev + */ + static int snd_seq_cell_alloc(struct snd_seq_pool *pool, + struct snd_seq_event_cell **cellp, +- int nonblock, struct file *file) ++ int nonblock, struct file *file, ++ struct mutex *mutexp) + { + struct snd_seq_event_cell *cell; + unsigned long flags; +@@ -245,7 +246,11 @@ static int snd_seq_cell_alloc(struct snd + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&pool->output_sleep, &wait); + spin_unlock_irq(&pool->lock); ++ if (mutexp) ++ mutex_unlock(mutexp); + schedule(); ++ if (mutexp) ++ mutex_lock(mutexp); + spin_lock_irq(&pool->lock); + remove_wait_queue(&pool->output_sleep, &wait); + /* interrupted? */ +@@ -288,7 +293,7 @@ __error: + */ + int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event, + struct snd_seq_event_cell **cellp, int nonblock, +- struct file *file) ++ struct file *file, struct mutex *mutexp) + { + int ncells, err; + unsigned int extlen; +@@ -305,7 +310,7 @@ int snd_seq_event_dup(struct snd_seq_poo + if (ncells >= pool->total_elements) + return -ENOMEM; + +- err = snd_seq_cell_alloc(pool, &cell, nonblock, file); ++ err = snd_seq_cell_alloc(pool, &cell, nonblock, file, mutexp); + if (err < 0) + return err; + +@@ -331,7 +336,8 @@ int snd_seq_event_dup(struct snd_seq_poo + int size = sizeof(struct snd_seq_event); + if (len < size) + size = len; +- err = snd_seq_cell_alloc(pool, &tmp, nonblock, file); ++ err = snd_seq_cell_alloc(pool, &tmp, nonblock, file, ++ mutexp); + if (err < 0) + goto __error; + if (cell->event.data.ext.ptr == NULL) +--- a/sound/core/seq/seq_memory.h ++++ b/sound/core/seq/seq_memory.h +@@ -66,7 +66,8 @@ struct snd_seq_pool { + void snd_seq_cell_free(struct snd_seq_event_cell *cell); + + int snd_seq_event_dup(struct snd_seq_pool *pool, struct snd_seq_event *event, +- struct snd_seq_event_cell **cellp, int nonblock, struct file *file); ++ struct snd_seq_event_cell **cellp, int nonblock, ++ struct file *file, struct mutex *mutexp); + + /* return number of unused (free) cells */ + static inline int snd_seq_unused_cells(struct snd_seq_pool *pool) diff --git a/queue-3.18/input-matrix_keypad-fix-race-when-disabling-interrupts.patch b/queue-3.18/input-matrix_keypad-fix-race-when-disabling-interrupts.patch new file mode 100644 index 00000000000..f16a687f284 --- /dev/null +++ b/queue-3.18/input-matrix_keypad-fix-race-when-disabling-interrupts.patch @@ -0,0 +1,40 @@ +From ea4f7bd2aca9f68470e9aac0fc9432fd180b1fe7 Mon Sep 17 00:00:00 2001 +From: Zhang Bo +Date: Mon, 5 Feb 2018 14:56:21 -0800 +Subject: Input: matrix_keypad - fix race when disabling interrupts + +From: Zhang Bo + +commit ea4f7bd2aca9f68470e9aac0fc9432fd180b1fe7 upstream. + +If matrix_keypad_stop() is executing and the keypad interrupt is triggered, +disable_row_irqs() may be called by both matrix_keypad_interrupt() and +matrix_keypad_stop() at the same time, causing interrupts to be disabled +twice and the keypad being "stuck" after resuming. + +Take lock when setting keypad->stopped to ensure that ISR will not race +with matrix_keypad_stop() disabling interrupts. + +Signed-off-by: Zhang Bo +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/keyboard/matrix_keypad.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/input/keyboard/matrix_keypad.c ++++ b/drivers/input/keyboard/matrix_keypad.c +@@ -216,8 +216,10 @@ static void matrix_keypad_stop(struct in + { + struct matrix_keypad *keypad = input_get_drvdata(dev); + ++ spin_lock_irq(&keypad->lock); + keypad->stopped = true; +- mb(); ++ spin_unlock_irq(&keypad->lock); ++ + flush_work(&keypad->work.work); + /* + * matrix_keypad_scan() will leave IRQs enabled; diff --git a/queue-3.18/mips-bmips-do-not-mask-ipis-during-suspend.patch b/queue-3.18/mips-bmips-do-not-mask-ipis-during-suspend.patch new file mode 100644 index 00000000000..d8c60557a3d --- /dev/null +++ b/queue-3.18/mips-bmips-do-not-mask-ipis-during-suspend.patch @@ -0,0 +1,54 @@ +From 06a3f0c9f2725f5d7c63c4203839373c9bd00c28 Mon Sep 17 00:00:00 2001 +From: Justin Chen +Date: Wed, 27 Sep 2017 17:15:15 -0700 +Subject: MIPS: BMIPS: Do not mask IPIs during suspend + +From: Justin Chen + +commit 06a3f0c9f2725f5d7c63c4203839373c9bd00c28 upstream. + +Commit a3e6c1eff548 ("MIPS: IRQ: Fix disable_irq on CPU IRQs") fixes an +issue where disable_irq did not actually disable the irq. The bug caused +our IPIs to not be disabled, which actually is the correct behavior. + +With the addition of commit a3e6c1eff548 ("MIPS: IRQ: Fix disable_irq on +CPU IRQs"), the IPIs were getting disabled going into suspend, thus +schedule_ipi() was not being called. This caused deadlocks where +schedulable task were not being scheduled and other cpus were waiting +for them to do something. + +Add the IRQF_NO_SUSPEND flag so an irq_disable will not be called on the +IPIs during suspend. + +Signed-off-by: Justin Chen +Fixes: a3e6c1eff548 ("MIPS: IRQ: Fix disabled_irq on CPU IRQs") +Cc: Florian Fainelli +Cc: linux-mips@linux-mips.org +Cc: stable@vger.kernel.org +Patchwork: https://patchwork.linux-mips.org/patch/17385/ +[jhogan@kernel.org: checkpatch: wrap long lines and fix commit refs] +Signed-off-by: James Hogan +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kernel/smp-bmips.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/arch/mips/kernel/smp-bmips.c ++++ b/arch/mips/kernel/smp-bmips.c +@@ -159,11 +159,11 @@ static void bmips_prepare_cpus(unsigned + return; + } + +- if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU, +- "smp_ipi0", NULL)) ++ if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, ++ IRQF_PERCPU | IRQF_NO_SUSPEND, "smp_ipi0", NULL)) + panic("Can't request IPI0 interrupt"); +- if (request_irq(IPI1_IRQ, bmips_ipi_interrupt, IRQF_PERCPU, +- "smp_ipi1", NULL)) ++ if (request_irq(IPI1_IRQ, bmips_ipi_interrupt, ++ IRQF_PERCPU | IRQF_NO_SUSPEND, "smp_ipi1", NULL)) + panic("Can't request IPI1 interrupt"); + } + diff --git a/queue-3.18/scsi-qla2xxx-fix-null-pointer-crash-due-to-active-timer-for-abts.patch b/queue-3.18/scsi-qla2xxx-fix-null-pointer-crash-due-to-active-timer-for-abts.patch new file mode 100644 index 00000000000..9eba472d72e --- /dev/null +++ b/queue-3.18/scsi-qla2xxx-fix-null-pointer-crash-due-to-active-timer-for-abts.patch @@ -0,0 +1,120 @@ +From 1514839b366417934e2f1328edb50ed1e8a719f5 Mon Sep 17 00:00:00 2001 +From: "himanshu.madhani@cavium.com" +Date: Mon, 12 Feb 2018 10:28:14 -0800 +Subject: scsi: qla2xxx: Fix NULL pointer crash due to active timer for ABTS + +From: himanshu.madhani@cavium.com + +commit 1514839b366417934e2f1328edb50ed1e8a719f5 upstream. + +This patch fixes NULL pointer crash due to active timer running for abort +IOCB. + +From crash dump analysis it was discoverd that get_next_timer_interrupt() +encountered a corrupted entry on the timer list. + + #9 [ffff95e1f6f0fd40] page_fault at ffffffff914fe8f8 + [exception RIP: get_next_timer_interrupt+440] + RIP: ffffffff90ea3088 RSP: ffff95e1f6f0fdf0 RFLAGS: 00010013 + RAX: ffff95e1f6451028 RBX: 000218e2389e5f40 RCX: 00000001232ad600 + RDX: 0000000000000001 RSI: ffff95e1f6f0fdf0 RDI: 0000000001232ad6 + RBP: ffff95e1f6f0fe40 R8: ffff95e1f6451188 R9: 0000000000000001 + R10: 0000000000000016 R11: 0000000000000016 R12: 00000001232ad5f6 + R13: ffff95e1f6450000 R14: ffff95e1f6f0fdf8 R15: ffff95e1f6f0fe10 + ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 + +Looking at the assembly of get_next_timer_interrupt(), address came +from %r8 (ffff95e1f6451188) which is pointing to list_head with single +entry at ffff95e5ff621178. + + 0xffffffff90ea307a : mov (%r8),%rdx + 0xffffffff90ea307d : cmp %r8,%rdx + 0xffffffff90ea3080 : je 0xffffffff90ea30a7 + 0xffffffff90ea3082 : nopw 0x0(%rax,%rax,1) + 0xffffffff90ea3088 : testb $0x1,0x18(%rdx) + + crash> rd ffff95e1f6451188 10 + ffff95e1f6451188: ffff95e5ff621178 ffff95e5ff621178 x.b.....x.b..... + ffff95e1f6451198: ffff95e1f6451198 ffff95e1f6451198 ..E.......E..... + ffff95e1f64511a8: ffff95e1f64511a8 ffff95e1f64511a8 ..E.......E..... + ffff95e1f64511b8: ffff95e77cf509a0 ffff95e77cf509a0 ...|.......|.... + ffff95e1f64511c8: ffff95e1f64511c8 ffff95e1f64511c8 ..E.......E..... + + crash> rd ffff95e5ff621178 10 + ffff95e5ff621178: 0000000000000001 ffff95e15936aa00 ..........6Y.... + ffff95e5ff621188: 0000000000000000 00000000ffffffff ................ + ffff95e5ff621198: 00000000000000a0 0000000000000010 ................ + ffff95e5ff6211a8: ffff95e5ff621198 000000000000000c ..b............. + ffff95e5ff6211b8: 00000f5800000000 ffff95e751f8d720 ....X... ..Q.... + + ffff95e5ff621178 belongs to freed mempool object at ffff95e5ff621080. + + CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE + ffff95dc7fd74d00 mnt_cache 384 19785 24948 594 16k + SLAB MEMORY NODE TOTAL ALLOCATED FREE + ffffdc5dabfd8800 ffff95e5ff620000 1 42 29 13 + FREE / [ALLOCATED] + ffff95e5ff621080 (cpu 6 cache) + +Examining the contents of that memory reveals a pointer to a constant string +in the driver, "abort\0", which is set by qla24xx_async_abort_cmd(). + + crash> rd ffffffffc059277c 20 + ffffffffc059277c: 6e490074726f6261 0074707572726574 abort.Interrupt. + ffffffffc059278c: 00676e696c6c6f50 6920726576697244 Polling.Driver i + ffffffffc059279c: 646f6d207325206e 6974736554000a65 n %s mode..Testi + ffffffffc05927ac: 636976656420676e 786c252074612065 ng device at %lx + ffffffffc05927bc: 6b63656843000a2e 646f727020676e69 ...Checking prod + ffffffffc05927cc: 6f20444920746375 0a2e706968632066 uct ID of chip.. + ffffffffc05927dc: 5120646e756f4600 204130303232414c .Found QLA2200A + ffffffffc05927ec: 43000a2e70696843 20676e696b636568 Chip...Checking + ffffffffc05927fc: 65786f626c69616d 6c636e69000a2e73 mailboxes...incl + ffffffffc059280c: 756e696c2f656475 616d2d616d642f78 ude/linux/dma-ma + + crash> struct -ox srb_iocb + struct srb_iocb { + union { + struct {...} logio; + struct {...} els_logo; + struct {...} tmf; + struct {...} fxiocb; + struct {...} abt; + struct ct_arg ctarg; + struct {...} mbx; + struct {...} nack; + [0x0 ] } u; + [0xb8] struct timer_list timer; + [0x108] void (*timeout)(void *); + } + SIZE: 0x110 + + crash> ! bc + ibase=16 + obase=10 + B8+40 + F8 + +The object is a srb_t, and at offset 0xf8 within that structure +(i.e. ffff95e5ff621080 + f8 -> ffff95e5ff621178) is a struct timer_list. + +Cc: #4.4+ +Fixes: 4440e46d5db7 ("[SCSI] qla2xxx: Add IOCB Abort command asynchronous handling.") +Signed-off-by: Himanshu Madhani +Reviewed-by: Johannes Thumshirn +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/qla2xxx/qla_init.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -365,6 +365,7 @@ qla24xx_abort_sp_done(void *data, void * + srb_t *sp = (srb_t *)ptr; + struct srb_iocb *abt = &sp->u.iocb_cmd; + ++ del_timer(&sp->u.iocb_cmd.timer); + complete(&abt->u.abt.comp); + } + diff --git a/queue-3.18/series b/queue-3.18/series index e69de29bb2d..70deaa0e9a2 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -0,0 +1,6 @@ +scsi-qla2xxx-fix-null-pointer-crash-due-to-active-timer-for-abts.patch +mips-bmips-do-not-mask-ipis-during-suspend.patch +input-matrix_keypad-fix-race-when-disabling-interrupts.patch +x86-mce-serialize-sysfs-changes.patch +alsa-seq-don-t-allow-resizing-pool-in-use.patch +alsa-seq-more-protection-for-concurrent-write-and-ioctl-races.patch diff --git a/queue-3.18/x86-mce-serialize-sysfs-changes.patch b/queue-3.18/x86-mce-serialize-sysfs-changes.patch new file mode 100644 index 00000000000..3bf915b963e --- /dev/null +++ b/queue-3.18/x86-mce-serialize-sysfs-changes.patch @@ -0,0 +1,115 @@ +From b3b7c4795ccab5be71f080774c45bbbcc75c2aaf Mon Sep 17 00:00:00 2001 +From: Seunghun Han +Date: Tue, 6 Mar 2018 15:21:43 +0100 +Subject: x86/MCE: Serialize sysfs changes + +From: Seunghun Han + +commit b3b7c4795ccab5be71f080774c45bbbcc75c2aaf upstream. + +The check_interval file in + + /sys/devices/system/machinecheck/machinecheck + +directory is a global timer value for MCE polling. If it is changed by one +CPU, mce_restart() broadcasts the event to other CPUs to delete and restart +the MCE polling timer and __mcheck_cpu_init_timer() reinitializes the +mce_timer variable. + +If more than one CPU writes a specific value to the check_interval file +concurrently, mce_timer is not protected from such concurrent accesses and +all kinds of explosions happen. Since only root can write to those sysfs +variables, the issue is not a big deal security-wise. + +However, concurrent writes to these configuration variables is void of +reason so the proper thing to do is to serialize the access with a mutex. + +Boris: + + - Make store_int_with_restart() use device_store_ulong() to filter out + negative intervals + - Limit min interval to 1 second + - Correct locking + - Massage commit message + +Signed-off-by: Seunghun Han +Signed-off-by: Borislav Petkov +Signed-off-by: Thomas Gleixner +Cc: Greg Kroah-Hartman +Cc: Tony Luck +Cc: linux-edac +Cc: stable@vger.kernel.org +Link: http://lkml.kernel.org/r/20180302202706.9434-1-kkamagui@gmail.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/mcheck/mce.c | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/cpu/mcheck/mce.c ++++ b/arch/x86/kernel/cpu/mcheck/mce.c +@@ -56,6 +56,9 @@ static DEFINE_MUTEX(mce_chrdev_read_mute + rcu_read_lock_sched_held() || \ + lockdep_is_held(&mce_chrdev_read_mutex)) + ++/* sysfs synchronization */ ++static DEFINE_MUTEX(mce_sysfs_mutex); ++ + #define CREATE_TRACE_POINTS + #include + +@@ -2183,6 +2186,7 @@ static ssize_t set_ignore_ce(struct devi + if (kstrtou64(buf, 0, &new) < 0) + return -EINVAL; + ++ mutex_lock(&mce_sysfs_mutex); + if (mca_cfg.ignore_ce ^ !!new) { + if (new) { + /* disable ce features */ +@@ -2195,6 +2199,8 @@ static ssize_t set_ignore_ce(struct devi + on_each_cpu(mce_enable_ce, (void *)1, 1); + } + } ++ mutex_unlock(&mce_sysfs_mutex); ++ + return size; + } + +@@ -2207,6 +2213,7 @@ static ssize_t set_cmci_disabled(struct + if (kstrtou64(buf, 0, &new) < 0) + return -EINVAL; + ++ mutex_lock(&mce_sysfs_mutex); + if (mca_cfg.cmci_disabled ^ !!new) { + if (new) { + /* disable cmci */ +@@ -2218,6 +2225,8 @@ static ssize_t set_cmci_disabled(struct + on_each_cpu(mce_enable_ce, NULL, 1); + } + } ++ mutex_unlock(&mce_sysfs_mutex); ++ + return size; + } + +@@ -2225,8 +2234,19 @@ static ssize_t store_int_with_restart(st + struct device_attribute *attr, + const char *buf, size_t size) + { +- ssize_t ret = device_store_int(s, attr, buf, size); ++ unsigned long old_check_interval = check_interval; ++ ssize_t ret = device_store_ulong(s, attr, buf, size); ++ ++ if (check_interval == old_check_interval) ++ return ret; ++ ++ if (check_interval < 1) ++ check_interval = 1; ++ ++ mutex_lock(&mce_sysfs_mutex); + mce_restart(); ++ mutex_unlock(&mce_sysfs_mutex); ++ + return ret; + } +