aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-13 18:39:06 -0500
committerJames Morris <jmorris@namei.org>2008-11-13 18:39:06 -0500
commit414c0708d0d60eccf8345c405ac81cf32c43e901 (patch)
tree5c3a5bd4c421176164475f87dc2f3cdb0de905e0 /ipc
parentda9592edebceeba1b9301beafe80ec8b9c2db0ce (diff)
CRED: Wrap task credential accesses in the SYSV IPC subsystem
Wrap access to task credentials so that they can be separated more easily from the task_struct during the introduction of COW creds. Change most current->(|e|s|fs)[ug]id to current_(|e|s|fs)[ug]id(). Change some task->e?[ug]id to task_e?[ug]id(). In some places it makes more sense to use RCU directly rather than a convenient wrapper; these will be addressed by later patches. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: James Morris <jmorris@namei.org> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'ipc')
-rw-r--r--ipc/mqueue.c6
-rw-r--r--ipc/shm.c5
-rw-r--r--ipc/util.c18
3 files changed, 19 insertions, 10 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 68eb857cfdea..abda5991d7e3 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -117,8 +117,8 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
117 inode = new_inode(sb); 117 inode = new_inode(sb);
118 if (inode) { 118 if (inode) {
119 inode->i_mode = mode; 119 inode->i_mode = mode;
120 inode->i_uid = current->fsuid; 120 inode->i_uid = current_fsuid();
121 inode->i_gid = current->fsgid; 121 inode->i_gid = current_fsgid();
122 inode->i_blocks = 0; 122 inode->i_blocks = 0;
123 inode->i_mtime = inode->i_ctime = inode->i_atime = 123 inode->i_mtime = inode->i_ctime = inode->i_atime =
124 CURRENT_TIME; 124 CURRENT_TIME;
@@ -507,7 +507,7 @@ static void __do_notify(struct mqueue_inode_info *info)
507 sig_i.si_code = SI_MESGQ; 507 sig_i.si_code = SI_MESGQ;
508 sig_i.si_value = info->notify.sigev_value; 508 sig_i.si_value = info->notify.sigev_value;
509 sig_i.si_pid = task_tgid_vnr(current); 509 sig_i.si_pid = task_tgid_vnr(current);
510 sig_i.si_uid = current->uid; 510 sig_i.si_uid = current_uid();
511 511
512 kill_pid_info(info->notify.sigev_signo, 512 kill_pid_info(info->notify.sigev_signo,
513 &sig_i, info->notify_owner); 513 &sig_i, info->notify_owner);
diff --git a/ipc/shm.c b/ipc/shm.c
index 867e5d6a55c2..0c3debbe32d5 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -752,9 +752,10 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
752 goto out_unlock; 752 goto out_unlock;
753 753
754 if (!capable(CAP_IPC_LOCK)) { 754 if (!capable(CAP_IPC_LOCK)) {
755 uid_t euid = current_euid();
755 err = -EPERM; 756 err = -EPERM;
756 if (current->euid != shp->shm_perm.uid && 757 if (euid != shp->shm_perm.uid &&
757 current->euid != shp->shm_perm.cuid) 758 euid != shp->shm_perm.cuid)
758 goto out_unlock; 759 goto out_unlock;
759 if (cmd == SHM_LOCK && 760 if (cmd == SHM_LOCK &&
760 !current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur) 761 !current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
diff --git a/ipc/util.c b/ipc/util.c
index 49b3ea615dc5..c8a76701b6c9 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)
@@ -272,8 +274,9 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
272 274
273 ids->in_use++; 275 ids->in_use++;
274 276
275 new->cuid = new->uid = current->euid; 277 current_euid_egid(&euid, &egid);
276 new->gid = new->cgid = current->egid; 278 new->cuid = new->uid = euid;
279 new->gid = new->cgid = egid;
277 280
278 new->seq = ids->seq++; 281 new->seq = ids->seq++;
279 if(ids->seq > ids->seq_max) 282 if(ids->seq > ids->seq_max)
@@ -616,13 +619,15 @@ void ipc_rcu_putref(void *ptr)
616 619
617int ipcperms (struct kern_ipc_perm *ipcp, short flag) 620int ipcperms (struct kern_ipc_perm *ipcp, short flag)
618{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */ 621{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
622 uid_t euid = current_euid();
619 int requested_mode, granted_mode, err; 623 int requested_mode, granted_mode, err;
620 624
621 if (unlikely((err = audit_ipc_obj(ipcp)))) 625 if (unlikely((err = audit_ipc_obj(ipcp))))
622 return err; 626 return err;
623 requested_mode = (flag >> 6) | (flag >> 3) | flag; 627 requested_mode = (flag >> 6) | (flag >> 3) | flag;
624 granted_mode = ipcp->mode; 628 granted_mode = ipcp->mode;
625 if (current->euid == ipcp->cuid || current->euid == ipcp->uid) 629 if (euid == ipcp->cuid ||
630 euid == ipcp->uid)
626 granted_mode >>= 6; 631 granted_mode >>= 6;
627 else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid)) 632 else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
628 granted_mode >>= 3; 633 granted_mode >>= 3;
@@ -784,6 +789,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
784 struct ipc64_perm *perm, int extra_perm) 789 struct ipc64_perm *perm, int extra_perm)
785{ 790{
786 struct kern_ipc_perm *ipcp; 791 struct kern_ipc_perm *ipcp;
792 uid_t euid;
787 int err; 793 int err;
788 794
789 down_write(&ids->rw_mutex); 795 down_write(&ids->rw_mutex);
@@ -803,8 +809,10 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
803 if (err) 809 if (err)
804 goto out_unlock; 810 goto out_unlock;
805 } 811 }
806 if (current->euid == ipcp->cuid || 812
807 current->euid == ipcp->uid || capable(CAP_SYS_ADMIN)) 813 euid = current_euid();
814 if (euid == ipcp->cuid ||
815 euid == ipcp->uid || capable(CAP_SYS_ADMIN))
808 return ipcp; 816 return ipcp;
809 817
810 err = -EPERM; 818 err = -EPERM;