diff options
author | David Howells <dhowells@redhat.com> | 2008-11-14 10:39:06 +1100 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-11-14 10:39:06 +1100 |
commit | 414c0708d0d60eccf8345c405ac81cf32c43e901 (patch) | |
tree | 5c3a5bd4c421176164475f87dc2f3cdb0de905e0 /ipc | |
parent | da9592edebceeba1b9301beafe80ec8b9c2db0ce (diff) | |
download | lwn-414c0708d0d60eccf8345c405ac81cf32c43e901.tar.gz lwn-414c0708d0d60eccf8345c405ac81cf32c43e901.zip |
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.c | 6 | ||||
-rw-r--r-- | ipc/shm.c | 5 | ||||
-rw-r--r-- | ipc/util.c | 18 |
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, inode = new_inode(sb); if (inode) { inode->i_mode = mode; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; + inode->i_uid = current_fsuid(); + inode->i_gid = current_fsgid(); inode->i_blocks = 0; inode->i_mtime = inode->i_ctime = inode->i_atime = CURRENT_TIME; @@ -507,7 +507,7 @@ static void __do_notify(struct mqueue_inode_info *info) sig_i.si_code = SI_MESGQ; sig_i.si_value = info->notify.sigev_value; sig_i.si_pid = task_tgid_vnr(current); - sig_i.si_uid = current->uid; + sig_i.si_uid = current_uid(); kill_pid_info(info->notify.sigev_signo, &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) goto out_unlock; if (!capable(CAP_IPC_LOCK)) { + uid_t euid = current_euid(); err = -EPERM; - if (current->euid != shp->shm_perm.uid && - current->euid != shp->shm_perm.cuid) + if (euid != shp->shm_perm.uid && + euid != shp->shm_perm.cuid) goto out_unlock; if (cmd == SHM_LOCK && !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) int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) { + uid_t euid; + gid_t egid; int id, err; if (size > IPCMNI) @@ -272,8 +274,9 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) ids->in_use++; - new->cuid = new->uid = current->euid; - new->gid = new->cgid = current->egid; + current_euid_egid(&euid, &egid); + new->cuid = new->uid = euid; + new->gid = new->cgid = egid; new->seq = ids->seq++; if(ids->seq > ids->seq_max) @@ -616,13 +619,15 @@ void ipc_rcu_putref(void *ptr) int ipcperms (struct kern_ipc_perm *ipcp, short flag) { /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */ + uid_t euid = current_euid(); int requested_mode, granted_mode, err; if (unlikely((err = audit_ipc_obj(ipcp)))) return err; requested_mode = (flag >> 6) | (flag >> 3) | flag; granted_mode = ipcp->mode; - if (current->euid == ipcp->cuid || current->euid == ipcp->uid) + if (euid == ipcp->cuid || + euid == ipcp->uid) granted_mode >>= 6; else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid)) granted_mode >>= 3; @@ -784,6 +789,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd, struct ipc64_perm *perm, int extra_perm) { struct kern_ipc_perm *ipcp; + uid_t euid; int err; down_write(&ids->rw_mutex); @@ -803,8 +809,10 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd, if (err) goto out_unlock; } - if (current->euid == ipcp->cuid || - current->euid == ipcp->uid || capable(CAP_SYS_ADMIN)) + + euid = current_euid(); + if (euid == ipcp->cuid || + euid == ipcp->uid || capable(CAP_SYS_ADMIN)) return ipcp; err = -EPERM; |