diff options
author | Rafael Aquini <aquini@redhat.com> | 2014-01-27 20:07:01 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-28 00:02:39 -0500 |
commit | 0f3d2b0135f4bdbfe47a99753923a64efd373d11 (patch) | |
tree | 4b211b7502e2412aedd94400bdcb012a2b5814b3 /ipc/msg.c | |
parent | 78f5009cc35eb5e52d276a046d90ee2f41b60f8c (diff) |
ipc: introduce ipc_valid_object() helper to sort out IPC_RMID races
After the locking semantics for the SysV IPC API got improved, a couple
of IPC_RMID race windows were opened because we ended up dropping the
'kern_ipc_perm.deleted' check performed way down in ipc_lock(). The
spotted races got sorted out by re-introducing the old test within the
racy critical sections.
This patch introduces ipc_valid_object() to consolidate the way we cope
with IPC_RMID races by using the same abstraction across the API
implementation.
Signed-off-by: Rafael Aquini <aquini@redhat.com>
Acked-by: Rik van Riel <riel@redhat.com>
Acked-by: Greg Thelen <gthelen@google.com>
Reviewed-by: Davidlohr Bueso <davidlohr@hp.com>
Cc: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc/msg.c')
-rw-r--r-- | ipc/msg.c | 7 |
1 files changed, 4 insertions, 3 deletions
@@ -696,7 +696,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, | |||
696 | goto out_unlock0; | 696 | goto out_unlock0; |
697 | 697 | ||
698 | /* raced with RMID? */ | 698 | /* raced with RMID? */ |
699 | if (msq->q_perm.deleted) { | 699 | if (!ipc_valid_object(&msq->q_perm)) { |
700 | err = -EIDRM; | 700 | err = -EIDRM; |
701 | goto out_unlock0; | 701 | goto out_unlock0; |
702 | } | 702 | } |
@@ -731,7 +731,8 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, | |||
731 | ipc_lock_object(&msq->q_perm); | 731 | ipc_lock_object(&msq->q_perm); |
732 | 732 | ||
733 | ipc_rcu_putref(msq, ipc_rcu_free); | 733 | ipc_rcu_putref(msq, ipc_rcu_free); |
734 | if (msq->q_perm.deleted) { | 734 | /* raced with RMID? */ |
735 | if (!ipc_valid_object(&msq->q_perm)) { | ||
735 | err = -EIDRM; | 736 | err = -EIDRM; |
736 | goto out_unlock0; | 737 | goto out_unlock0; |
737 | } | 738 | } |
@@ -909,7 +910,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl | |||
909 | ipc_lock_object(&msq->q_perm); | 910 | ipc_lock_object(&msq->q_perm); |
910 | 911 | ||
911 | /* raced with RMID? */ | 912 | /* raced with RMID? */ |
912 | if (msq->q_perm.deleted) { | 913 | if (!ipc_valid_object(&msq->q_perm)) { |
913 | msg = ERR_PTR(-EIDRM); | 914 | msg = ERR_PTR(-EIDRM); |
914 | goto out_unlock0; | 915 | goto out_unlock0; |
915 | } | 916 | } |