diff options
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/shm.c | 10 | ||||
-rw-r--r-- | ipc/util.c | 6 |
2 files changed, 12 insertions, 4 deletions
diff --git a/ipc/shm.c b/ipc/shm.c index 748933e376ca..70a41171b8bb 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -173,6 +173,14 @@ static inline struct shmid_kernel *shm_obtain_object_check(struct ipc_namespace return container_of(ipcp, struct shmid_kernel, shm_perm); } +static inline bool is_shm_in_ns(struct ipc_namespace *ns, struct shmid_kernel *shp) +{ + int idx = ipcid_to_idx(shp->shm_perm.id); + struct shmid_kernel *tshp = shm_obtain_object(ns, idx); + + return !IS_ERR(tshp) && tshp == shp; +} + /* * shm_lock_(check_) routines are called in the paths where the rwsem * is not necessarily held. @@ -415,7 +423,7 @@ void exit_shm(struct task_struct *task) list_for_each_entry_safe(shp, n, &task->sysvshm.shm_clist, shm_clist) { shp->shm_creator = NULL; - if (shm_may_destroy(ns, shp)) { + if (is_shm_in_ns(ns, shp) && shm_may_destroy(ns, shp)) { shm_lock_by_ptr(shp); shm_destroy(ns, shp); } diff --git a/ipc/util.c b/ipc/util.c index 0027e47626b7..45bb8ce6c42c 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -447,8 +447,8 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, static void ipc_kht_remove(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) { if (ipcp->key != IPC_PRIVATE) - rhashtable_remove_fast(&ids->key_ht, &ipcp->khtnode, - ipc_kht_params); + WARN_ON(rhashtable_remove_fast(&ids->key_ht, &ipcp->khtnode, + ipc_kht_params)); } /** @@ -498,7 +498,7 @@ void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) { int idx = ipcid_to_idx(ipcp->id); - idr_remove(&ids->ipcs_idr, idx); + WARN_ON(idr_remove(&ids->ipcs_idr, idx) != ipcp); ipc_kht_remove(ids, ipcp); ids->in_use--; ipcp->deleted = true; |