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
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-id: <1390812301-4102-1-git-send-email-r.baldyga@samsung.com>
Date:	Mon, 27 Jan 2014 09:45:01 +0100
From:	Robert Baldyga <r.baldyga@...sung.com>
To:	viro@...iv.linux.org.uk
Cc:	bcrl@...ck.org, kmo@...erainc.com, linux-fsdevel@...r.kernel.org,
	linux-aio@...ck.org, linux-kernel@...r.kernel.org,
	m.szyprowski@...sung.com, Robert Baldyga <r.baldyga@...sung.com>
Subject: [PATCH] aio: fix kiocb_cancel() funcition

This patch solves problem related with lack of possibility to call
aio_complete() from cancel callback. It was because it needs to lock
ctx->ctx_lock which is always locked before kiocb_cancel() call. So there
was no way to complete request properly.

Now spinlock is unlocked before cancel callback function call, so spinlock
recursion will not occur in case of aio_complete() call. After cancel function
call spinlock is locked back.

There is also __must_hold() macro added for kiocb_cancel() function, to allow
sparse spin lock checking.

Signed-off-by: Robert Baldyga <r.baldyga@...sung.com>
---

This patch was created according to suggestions of Benjamin LaHaise
(https://lkml.org/lkml/2014/1/23/336).

 fs/aio.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/fs/aio.c b/fs/aio.c
index 062a5f6..6d5cd9e 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -472,8 +472,10 @@ void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel)
 EXPORT_SYMBOL(kiocb_set_cancel_fn);
 
 static int kiocb_cancel(struct kioctx *ctx, struct kiocb *kiocb)
+			__must_hold(&ctx->ctx_lock)
 {
 	kiocb_cancel_fn *old, *cancel;
+	int ret;
 
 	/*
 	 * Don't want to set kiocb->ki_cancel = KIOCB_CANCELLED unless it
@@ -489,7 +491,15 @@ static int kiocb_cancel(struct kioctx *ctx, struct kiocb *kiocb)
 		cancel = cmpxchg(&kiocb->ki_cancel, old, KIOCB_CANCELLED);
 	} while (cancel != old);
 
-	return cancel(kiocb);
+	/*
+	 * cancel() function may call aio_complete function, which needs to
+	 * lock ctx->ctx_lock, so we call cancel() with spinlock unlocked
+	 */
+	spin_unlock(&ctx->ctx_lock);
+	ret = cancel(kiocb);
+	spin_lock(&ctx->ctx_lock);
+
+	return ret;
 }
 
 static void free_ioctx(struct work_struct *work)
-- 
1.7.9.5

--
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

Powered by Openwall GNU/*/Linux Powered by OpenVZ