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
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 14 Jul 2014 13:12:27 -0400
From:	Benjamin LaHaise <>
To:	Linus Torvalds <>,
	Robert Elliot <>
	Jens Axboe <>,
	Christoph Hellwig <>,
Subject: [PATCH] aio: protect reqs_available updates from changes in interrupt handlers

Hello everyone,

Please pull the following commit (263782c1c95bbddbb022dc092fd89a36bb8d5577) 
from git:// to fix an aio bug reported by Robert 
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 <>
Tested-by: Robert Elliot <>
Signed-off-by: Benjamin LaHaise <>
Cc: Jens Axboe <>, Christoph Hellwig <>
 fs/aio.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/fs/aio.c b/fs/aio.c
index 955947e..1c9c5f0 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -830,16 +830,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;
 	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);
@@ -847,10 +851,12 @@ static bool get_reqs_available(struct kioctx *ctx)
 	struct kioctx_cpu *kcpu;
 	bool ret = false;
+	unsigned long flags;
 	kcpu = this_cpu_ptr(ctx->cpu);
+	local_irq_save(flags);
 	if (!kcpu->reqs_available) {
 		int old, avail = atomic_read(&ctx->reqs_available);
@@ -869,6 +875,7 @@ static bool get_reqs_available(struct kioctx *ctx)
 	ret = true;
+	local_irq_restore(flags);
 	return ret;

"Thought is the essence of where you are now."
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at
Please read the FAQ at

Powered by blists - more mailing lists