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>
This commit is contained in:
parent
da9592edeb
commit
414c0708d0
3 changed files with 19 additions and 10 deletions
|
@ -117,8 +117,8 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
|
||||||
inode = new_inode(sb);
|
inode = new_inode(sb);
|
||||||
if (inode) {
|
if (inode) {
|
||||||
inode->i_mode = mode;
|
inode->i_mode = mode;
|
||||||
inode->i_uid = current->fsuid;
|
inode->i_uid = current_fsuid();
|
||||||
inode->i_gid = current->fsgid;
|
inode->i_gid = current_fsgid();
|
||||||
inode->i_blocks = 0;
|
inode->i_blocks = 0;
|
||||||
inode->i_mtime = inode->i_ctime = inode->i_atime =
|
inode->i_mtime = inode->i_ctime = inode->i_atime =
|
||||||
CURRENT_TIME;
|
CURRENT_TIME;
|
||||||
|
@ -507,7 +507,7 @@ static void __do_notify(struct mqueue_inode_info *info)
|
||||||
sig_i.si_code = SI_MESGQ;
|
sig_i.si_code = SI_MESGQ;
|
||||||
sig_i.si_value = info->notify.sigev_value;
|
sig_i.si_value = info->notify.sigev_value;
|
||||||
sig_i.si_pid = task_tgid_vnr(current);
|
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,
|
kill_pid_info(info->notify.sigev_signo,
|
||||||
&sig_i, info->notify_owner);
|
&sig_i, info->notify_owner);
|
||||||
|
|
|
@ -752,9 +752,10 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
if (!capable(CAP_IPC_LOCK)) {
|
if (!capable(CAP_IPC_LOCK)) {
|
||||||
|
uid_t euid = current_euid();
|
||||||
err = -EPERM;
|
err = -EPERM;
|
||||||
if (current->euid != shp->shm_perm.uid &&
|
if (euid != shp->shm_perm.uid &&
|
||||||
current->euid != shp->shm_perm.cuid)
|
euid != shp->shm_perm.cuid)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
if (cmd == SHM_LOCK &&
|
if (cmd == SHM_LOCK &&
|
||||||
!current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
|
!current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
|
||||||
|
|
18
ipc/util.c
18
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)
|
int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
|
||||||
{
|
{
|
||||||
|
uid_t euid;
|
||||||
|
gid_t egid;
|
||||||
int id, err;
|
int id, err;
|
||||||
|
|
||||||
if (size > IPCMNI)
|
if (size > IPCMNI)
|
||||||
|
@ -272,8 +274,9 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
|
||||||
|
|
||||||
ids->in_use++;
|
ids->in_use++;
|
||||||
|
|
||||||
new->cuid = new->uid = current->euid;
|
current_euid_egid(&euid, &egid);
|
||||||
new->gid = new->cgid = current->egid;
|
new->cuid = new->uid = euid;
|
||||||
|
new->gid = new->cgid = egid;
|
||||||
|
|
||||||
new->seq = ids->seq++;
|
new->seq = ids->seq++;
|
||||||
if(ids->seq > ids->seq_max)
|
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)
|
int ipcperms (struct kern_ipc_perm *ipcp, short flag)
|
||||||
{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
|
{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
|
||||||
|
uid_t euid = current_euid();
|
||||||
int requested_mode, granted_mode, err;
|
int requested_mode, granted_mode, err;
|
||||||
|
|
||||||
if (unlikely((err = audit_ipc_obj(ipcp))))
|
if (unlikely((err = audit_ipc_obj(ipcp))))
|
||||||
return err;
|
return err;
|
||||||
requested_mode = (flag >> 6) | (flag >> 3) | flag;
|
requested_mode = (flag >> 6) | (flag >> 3) | flag;
|
||||||
granted_mode = ipcp->mode;
|
granted_mode = ipcp->mode;
|
||||||
if (current->euid == ipcp->cuid || current->euid == ipcp->uid)
|
if (euid == ipcp->cuid ||
|
||||||
|
euid == ipcp->uid)
|
||||||
granted_mode >>= 6;
|
granted_mode >>= 6;
|
||||||
else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
|
else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
|
||||||
granted_mode >>= 3;
|
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 ipc64_perm *perm, int extra_perm)
|
||||||
{
|
{
|
||||||
struct kern_ipc_perm *ipcp;
|
struct kern_ipc_perm *ipcp;
|
||||||
|
uid_t euid;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
down_write(&ids->rw_mutex);
|
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)
|
if (err)
|
||||||
goto out_unlock;
|
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;
|
return ipcp;
|
||||||
|
|
||||||
err = -EPERM;
|
err = -EPERM;
|
||||||
|
|
Loading…
Reference in a new issue