aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/util.c')
-rw-r--r--ipc/util.c36
1 files changed, 18 insertions, 18 deletions
diff --git a/ipc/util.c b/ipc/util.c
index 361fd1c96fcf..7585a72e259b 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -258,6 +258,8 @@ int ipc_get_maxid(struct ipc_ids *ids)
258 258
259int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) 259int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
260{ 260{
261 uid_t euid;
262 gid_t egid;
261 int id, err; 263 int id, err;
262 264
263 if (size > IPCMNI) 265 if (size > IPCMNI)
@@ -280,8 +282,9 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
280 282
281 ids->in_use++; 283 ids->in_use++;
282 284
283 new->cuid = new->uid = current->euid; 285 current_euid_egid(&euid, &egid);
284 new->gid = new->cgid = current->egid; 286 new->cuid = new->uid = euid;
287 new->gid = new->cgid = egid;
285 288
286 new->seq = ids->seq++; 289 new->seq = ids->seq++;
287 if(ids->seq > ids->seq_max) 290 if(ids->seq > ids->seq_max)
@@ -620,13 +623,14 @@ void ipc_rcu_putref(void *ptr)
620 623
621int ipcperms (struct kern_ipc_perm *ipcp, short flag) 624int ipcperms (struct kern_ipc_perm *ipcp, short flag)
622{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */ 625{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
623 int requested_mode, granted_mode, err; 626 uid_t euid = current_euid();
627 int requested_mode, granted_mode;
624 628
625 if (unlikely((err = audit_ipc_obj(ipcp)))) 629 audit_ipc_obj(ipcp);
626 return err;
627 requested_mode = (flag >> 6) | (flag >> 3) | flag; 630 requested_mode = (flag >> 6) | (flag >> 3) | flag;
628 granted_mode = ipcp->mode; 631 granted_mode = ipcp->mode;
629 if (current->euid == ipcp->cuid || current->euid == ipcp->uid) 632 if (euid == ipcp->cuid ||
633 euid == ipcp->uid)
630 granted_mode >>= 6; 634 granted_mode >>= 6;
631 else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid)) 635 else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
632 granted_mode >>= 3; 636 granted_mode >>= 3;
@@ -788,6 +792,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
788 struct ipc64_perm *perm, int extra_perm) 792 struct ipc64_perm *perm, int extra_perm)
789{ 793{
790 struct kern_ipc_perm *ipcp; 794 struct kern_ipc_perm *ipcp;
795 uid_t euid;
791 int err; 796 int err;
792 797
793 down_write(&ids->rw_mutex); 798 down_write(&ids->rw_mutex);
@@ -797,22 +802,17 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
797 goto out_up; 802 goto out_up;
798 } 803 }
799 804
800 err = audit_ipc_obj(ipcp); 805 audit_ipc_obj(ipcp);
801 if (err) 806 if (cmd == IPC_SET)
802 goto out_unlock; 807 audit_ipc_set_perm(extra_perm, perm->uid,
803
804 if (cmd == IPC_SET) {
805 err = audit_ipc_set_perm(extra_perm, perm->uid,
806 perm->gid, perm->mode); 808 perm->gid, perm->mode);
807 if (err) 809
808 goto out_unlock; 810 euid = current_euid();
809 } 811 if (euid == ipcp->cuid ||
810 if (current->euid == ipcp->cuid || 812 euid == ipcp->uid || capable(CAP_SYS_ADMIN))
811 current->euid == ipcp->uid || capable(CAP_SYS_ADMIN))
812 return ipcp; 813 return ipcp;
813 814
814 err = -EPERM; 815 err = -EPERM;
815out_unlock:
816 ipc_unlock(ipcp); 816 ipc_unlock(ipcp);
817out_up: 817out_up:
818 up_write(&ids->rw_mutex); 818 up_write(&ids->rw_mutex);