summaryrefslogtreecommitdiffstatshomepage
path: root/ipc
diff options
context:
space:
mode:
authorDavidlohr Bueso <dave@stgolabs.net>2018-08-21 21:01:41 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-22 09:52:52 -0800
commit82061c57ce93caa50fd01c11f8eb30ddc4c4bd75 (patch)
treee8f8077ee5442eec5e372b343ce117b43bf538e7 /ipc
parent2e5ceb452c9b7f0a30c87bd61c01260e3d8464ad (diff)
downloadlinux-stable-82061c57ce93caa50fd01c11f8eb30ddc4c4bd75.tar.gz
linux-stable-82061c57ce93caa50fd01c11f8eb30ddc4c4bd75.tar.bz2
linux-stable-82061c57ce93caa50fd01c11f8eb30ddc4c4bd75.tar.xz
linux-stable-82061c57ce93caa50fd01c11f8eb30ddc4c4bd75.zip
ipc: drop ipc_lock()
ipc/util.c contains multiple functions to get the ipc object pointer given an id number. There are two sets of function: One set verifies the sequence counter part of the id number, other functions do not check the sequence counter. The standard for function names in ipc/util.c is - ..._check() functions verify the sequence counter - ..._idr() functions do not verify the sequence counter ipc_lock() is an exception: It does not verify the sequence counter value, but this is not obvious from the function name. Furthermore, shm.c is the only user of this helper. Thus, we can simply move the logic into shm_lock() and get rid of the function altogether. [manfred@colorfullife.com: most of changelog] Link: http://lkml.kernel.org/r/20180712185241.4017-7-manfred@colorfullife.com Signed-off-by: Davidlohr Bueso <dbueso@suse.de> Signed-off-by: Manfred Spraul <manfred@colorfullife.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: Kees Cook <keescook@chromium.org> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Cc: Michal Hocko <mhocko@suse.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc')
-rw-r--r--ipc/shm.c29
-rw-r--r--ipc/util.c36
-rw-r--r--ipc/util.h1
3 files changed, 23 insertions, 43 deletions
diff --git a/ipc/shm.c b/ipc/shm.c
index a413ddf74dac..4c7ae625d996 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -180,16 +180,33 @@ static inline struct shmid_kernel *shm_obtain_object_check(struct ipc_namespace
180 */ 180 */
181static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id) 181static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id)
182{ 182{
183 struct kern_ipc_perm *ipcp = ipc_lock(&shm_ids(ns), id); 183 struct kern_ipc_perm *ipcp;
184
185 rcu_read_lock();
186 ipcp = ipc_obtain_object_idr(&shm_ids(ns), id);
187 if (IS_ERR(ipcp))
188 goto err;
184 189
190 ipc_lock_object(ipcp);
191 /*
192 * ipc_rmid() may have already freed the ID while ipc_lock_object()
193 * was spinning: here verify that the structure is still valid.
194 * Upon races with RMID, return -EIDRM, thus indicating that
195 * the ID points to a removed identifier.
196 */
197 if (ipc_valid_object(ipcp)) {
198 /* return a locked ipc object upon success */
199 return container_of(ipcp, struct shmid_kernel, shm_perm);
200 }
201
202 ipc_unlock_object(ipcp);
203err:
204 rcu_read_unlock();
185 /* 205 /*
186 * Callers of shm_lock() must validate the status of the returned ipc 206 * Callers of shm_lock() must validate the status of the returned ipc
187 * object pointer (as returned by ipc_lock()), and error out as 207 * object pointer and error out as appropriate.
188 * appropriate.
189 */ 208 */
190 if (IS_ERR(ipcp)) 209 return (void *)ipcp;
191 return (void *)ipcp;
192 return container_of(ipcp, struct shmid_kernel, shm_perm);
193} 210}
194 211
195static inline void shm_lock_by_ptr(struct shmid_kernel *ipcp) 212static inline void shm_lock_by_ptr(struct shmid_kernel *ipcp)
diff --git a/ipc/util.c b/ipc/util.c
index dcb437095cbd..bd1863b6ed39 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -589,42 +589,6 @@ struct kern_ipc_perm *ipc_obtain_object_idr(struct ipc_ids *ids, int id)
589} 589}
590 590
591/** 591/**
592 * ipc_lock - lock an ipc structure without rwsem held
593 * @ids: ipc identifier set
594 * @id: ipc id to look for
595 *
596 * Look for an id in the ipc ids idr and lock the associated ipc object.
597 *
598 * The ipc object is locked on successful exit.
599 */
600struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id)
601{
602 struct kern_ipc_perm *out;
603
604 rcu_read_lock();
605 out = ipc_obtain_object_idr(ids, id);
606 if (IS_ERR(out))
607 goto err;
608
609 spin_lock(&out->lock);
610
611 /*
612 * ipc_rmid() may have already freed the ID while ipc_lock()
613 * was spinning: here verify that the structure is still valid.
614 * Upon races with RMID, return -EIDRM, thus indicating that
615 * the ID points to a removed identifier.
616 */
617 if (ipc_valid_object(out))
618 return out;
619
620 spin_unlock(&out->lock);
621 out = ERR_PTR(-EIDRM);
622err:
623 rcu_read_unlock();
624 return out;
625}
626
627/**
628 * ipc_obtain_object_check 592 * ipc_obtain_object_check
629 * @ids: ipc identifier set 593 * @ids: ipc identifier set
630 * @id: ipc id to look for 594 * @id: ipc id to look for
diff --git a/ipc/util.h b/ipc/util.h
index fcf81425ae98..e3c47b21db93 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -142,7 +142,6 @@ int ipc_rcu_getref(struct kern_ipc_perm *ptr);
142void ipc_rcu_putref(struct kern_ipc_perm *ptr, 142void ipc_rcu_putref(struct kern_ipc_perm *ptr,
143 void (*func)(struct rcu_head *head)); 143 void (*func)(struct rcu_head *head));
144 144
145struct kern_ipc_perm *ipc_lock(struct ipc_ids *, int);
146struct kern_ipc_perm *ipc_obtain_object_idr(struct ipc_ids *ids, int id); 145struct kern_ipc_perm *ipc_obtain_object_idr(struct ipc_ids *ids, int id);
147 146
148void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out); 147void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out);