lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Fri, 8 Aug 2014 13:39:14 -0700 From: Kamal Mostafa <kamal@...onical.com> To: linux-kernel@...r.kernel.org, stable@...r.kernel.org, kernel-team@...ts.ubuntu.com Cc: Benjamin LaHaise <bcrl@...ck.org>, Jens Axboe <axboe@...nel.dk>, Kamal Mostafa <kamal@...onical.com> Subject: [PATCH 3.13 131/259] aio: protect reqs_available updates from changes in interrupt handlers 3.13.11.6 -stable review patch. If anyone has any objections, please let me know. ------------------ From: Benjamin LaHaise <bcrl@...ck.org> commit 263782c1c95bbddbb022dc092fd89a36bb8d5577 upstream. As of commit f8567a3845ac05bb28f3c1b478ef752762bd39ef it is now possible to have put_reqs_available() called from irq context. While put_reqs_available() is per cpu, it did not protect itself from interrupts on the same CPU. This lead to aio_complete() corrupting the available io requests count when run under a heavy O_DIRECT workloads as reported by Robert Elliott. Fix this by disabling irq updates around the per cpu batch updates of reqs_available. Many thanks to Robert and folks for testing and tracking this down. Reported-by: Robert Elliot <Elliott@...com> Tested-by: Robert Elliot <Elliott@...com> Signed-off-by: Benjamin LaHaise <bcrl@...ck.org> Cc: Jens Axboe <axboe@...nel.dk>, Christoph Hellwig <hch@...radead.org> Signed-off-by: Kamal Mostafa <kamal@...onical.com> --- fs/aio.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/aio.c b/fs/aio.c index 19e7d95..a0d9e43 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -816,16 +816,20 @@ void exit_aio(struct mm_struct *mm) static void put_reqs_available(struct kioctx *ctx, unsigned nr) { struct kioctx_cpu *kcpu; + unsigned long flags; preempt_disable(); kcpu = this_cpu_ptr(ctx->cpu); + local_irq_save(flags); kcpu->reqs_available += nr; + while (kcpu->reqs_available >= ctx->req_batch * 2) { kcpu->reqs_available -= ctx->req_batch; atomic_add(ctx->req_batch, &ctx->reqs_available); } + local_irq_restore(flags); preempt_enable(); } @@ -833,10 +837,12 @@ static bool get_reqs_available(struct kioctx *ctx) { struct kioctx_cpu *kcpu; bool ret = false; + unsigned long flags; preempt_disable(); kcpu = this_cpu_ptr(ctx->cpu); + local_irq_save(flags); if (!kcpu->reqs_available) { int old, avail = atomic_read(&ctx->reqs_available); @@ -855,6 +861,7 @@ static bool get_reqs_available(struct kioctx *ctx) ret = true; kcpu->reqs_available--; out: + local_irq_restore(flags); preempt_enable(); return ret; } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists