ipc/shm: serialize orphan cleanup with shm_nattch updates
shm_destroy_orphaned() walks the shm idr under shm_ids(ns).rwsem, but that
does not serialize all fields tested by shm_may_destroy(). In particular,
shm_nattch is updated while holding shm_perm.lock, and attach paths can do
that without holding the rwsem.
Do not decide that an orphaned segment is unused before taking the object
lock. Move the shm_may_destroy() check under shm_perm.lock, matching the
other destroy paths, and unlock the segment when it no longer qualifies
for removal.
Link: https://lore.kernel.org/9d97cc1031de2d0bace0edf3a668818aa2f4eca6.1777410234.git.zylzyl2333@gmail.com
Fixes: 4c677e2eef ("shm: optimize locking and ipc_namespace getting")
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Signed-off-by: Yilin Zhu <zylzyl2333@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jeongjun Park <aha310510@gmail.com>
Cc: Kees Cook <kees@kernel.org>
Cc: Liam Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Serge Hallyn <sergeh@kernel.org>
Cc: Vasiliy Kulikov <segoon@openwall.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Serge Hallyn <serge@hallyn.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
9d7bea186b
commit
2e5c6f4fd4
1 changed files with 6 additions and 4 deletions
10
ipc/shm.c
10
ipc/shm.c
|
|
@ -418,15 +418,17 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data)
|
||||||
* We want to destroy segments without users and with already
|
* We want to destroy segments without users and with already
|
||||||
* exit'ed originating process.
|
* exit'ed originating process.
|
||||||
*
|
*
|
||||||
* As shp->* are changed under rwsem, it's safe to skip shp locking.
|
* shm_nattch can be changed under shm_perm.lock without holding the
|
||||||
|
* rwsem, so take the object lock before checking shm_may_destroy().
|
||||||
*/
|
*/
|
||||||
if (!list_empty(&shp->shm_clist))
|
if (!list_empty(&shp->shm_clist))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (shm_may_destroy(shp)) {
|
shm_lock_by_ptr(shp);
|
||||||
shm_lock_by_ptr(shp);
|
if (shm_may_destroy(shp))
|
||||||
shm_destroy(ns, shp);
|
shm_destroy(ns, shp);
|
||||||
}
|
else
|
||||||
|
shm_unlock(shp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue