summaryrefslogtreecommitdiffstats
path: root/ipc/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/util.c')
-rw-r--r--ipc/util.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/ipc/util.c b/ipc/util.c
index 813804ebdeba..3df0af3158a5 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -824,11 +824,28 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
824 struct ipc64_perm *perm, int extra_perm) 824 struct ipc64_perm *perm, int extra_perm)
825{ 825{
826 struct kern_ipc_perm *ipcp; 826 struct kern_ipc_perm *ipcp;
827
828 ipcp = ipcctl_pre_down_nolock(ns, ids, id, cmd, perm, extra_perm);
829 if (IS_ERR(ipcp))
830 goto out;
831
832 spin_lock(&ipcp->lock);
833out:
834 return ipcp;
835}
836
837struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
838 struct ipc_ids *ids, int id, int cmd,
839 struct ipc64_perm *perm, int extra_perm)
840{
827 kuid_t euid; 841 kuid_t euid;
828 int err; 842 int err = -EPERM;
843 struct kern_ipc_perm *ipcp;
829 844
830 down_write(&ids->rw_mutex); 845 down_write(&ids->rw_mutex);
831 ipcp = ipc_lock_check(ids, id); 846 rcu_read_lock();
847
848 ipcp = ipc_obtain_object_check(ids, id);
832 if (IS_ERR(ipcp)) { 849 if (IS_ERR(ipcp)) {
833 err = PTR_ERR(ipcp); 850 err = PTR_ERR(ipcp);
834 goto out_up; 851 goto out_up;
@@ -837,17 +854,21 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
837 audit_ipc_obj(ipcp); 854 audit_ipc_obj(ipcp);
838 if (cmd == IPC_SET) 855 if (cmd == IPC_SET)
839 audit_ipc_set_perm(extra_perm, perm->uid, 856 audit_ipc_set_perm(extra_perm, perm->uid,
840 perm->gid, perm->mode); 857 perm->gid, perm->mode);
841 858
842 euid = current_euid(); 859 euid = current_euid();
843 if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid) || 860 if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid) ||
844 ns_capable(ns->user_ns, CAP_SYS_ADMIN)) 861 ns_capable(ns->user_ns, CAP_SYS_ADMIN))
845 return ipcp; 862 return ipcp;
846 863
847 err = -EPERM;
848 ipc_unlock(ipcp);
849out_up: 864out_up:
865 /*
866 * Unsuccessful lookup, unlock and return
867 * the corresponding error.
868 */
869 rcu_read_unlock();
850 up_write(&ids->rw_mutex); 870 up_write(&ids->rw_mutex);
871
851 return ERR_PTR(err); 872 return ERR_PTR(err);
852} 873}
853 874