Skip to content

Commit

Permalink
CRED: Separate task security context from task_struct
Browse files Browse the repository at this point in the history
Separate the task security context from task_struct.  At this point, the
security data is temporarily embedded in the task_struct with two pointers
pointing to it.

Note that the Alpha arch is altered as it refers to (E)UID and (E)GID in
entry.S via asm-offsets.

With comment fixes Signed-off-by: Marc Dionne <[email protected]>

Signed-off-by: David Howells <[email protected]>
Acked-by: James Morris <[email protected]>
Acked-by: Serge Hallyn <[email protected]>
Signed-off-by: James Morris <[email protected]>
  • Loading branch information
dhowells authored and James Morris committed Nov 13, 2008
1 parent 15a2460 commit b6dff3e
Show file tree
Hide file tree
Showing 63 changed files with 832 additions and 677 deletions.
11 changes: 7 additions & 4 deletions arch/alpha/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,18 @@ void foo(void)
BLANK();

DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
DEFINE(TASK_UID, offsetof(struct task_struct, uid));
DEFINE(TASK_EUID, offsetof(struct task_struct, euid));
DEFINE(TASK_GID, offsetof(struct task_struct, gid));
DEFINE(TASK_EGID, offsetof(struct task_struct, egid));
DEFINE(TASK_CRED, offsetof(struct task_struct, cred));
DEFINE(TASK_REAL_PARENT, offsetof(struct task_struct, real_parent));
DEFINE(TASK_GROUP_LEADER, offsetof(struct task_struct, group_leader));
DEFINE(TASK_TGID, offsetof(struct task_struct, tgid));
BLANK();

DEFINE(CRED_UID, offsetof(struct cred, uid));
DEFINE(CRED_EUID, offsetof(struct cred, euid));
DEFINE(CRED_GID, offsetof(struct cred, gid));
DEFINE(CRED_EGID, offsetof(struct cred, egid));
BLANK();

DEFINE(SIZEOF_PT_REGS, sizeof(struct pt_regs));
DEFINE(PT_PTRACED, PT_PTRACED);
DEFINE(CLONE_VM, CLONE_VM);
Expand Down
10 changes: 6 additions & 4 deletions arch/alpha/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -850,8 +850,9 @@ osf_getpriority:
sys_getxuid:
.prologue 0
ldq $2, TI_TASK($8)
ldl $0, TASK_UID($2)
ldl $1, TASK_EUID($2)
ldq $3, TASK_CRED($2)
ldl $0, CRED_UID($3)
ldl $1, CRED_EUID($3)
stq $1, 80($sp)
ret
.end sys_getxuid
Expand All @@ -862,8 +863,9 @@ sys_getxuid:
sys_getxgid:
.prologue 0
ldq $2, TI_TASK($8)
ldl $0, TASK_GID($2)
ldl $1, TASK_EGID($2)
ldq $3, TASK_CRED($2)
ldl $0, CRED_GID($3)
ldl $1, CRED_EGID($3)
stq $1, 80($sp)
ret
.end sys_getxgid
Expand Down
8 changes: 4 additions & 4 deletions arch/ia64/ia32/sys_ia32.c
Original file line number Diff line number Diff line change
Expand Up @@ -1772,20 +1772,20 @@ sys32_getgroups16 (int gidsetsize, short __user *grouplist)
if (gidsetsize < 0)
return -EINVAL;

get_group_info(current->group_info);
i = current->group_info->ngroups;
get_group_info(current->cred->group_info);
i = current->cred->group_info->ngroups;
if (gidsetsize) {
if (i > gidsetsize) {
i = -EINVAL;
goto out;
}
if (groups16_to_user(grouplist, current->group_info)) {
if (groups16_to_user(grouplist, current->cred->group_info)) {
i = -EFAULT;
goto out;
}
}
out:
put_group_info(current->group_info);
put_group_info(current->cred->group_info);
return i;
}

Expand Down
4 changes: 2 additions & 2 deletions arch/mips/kernel/kspd.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ static unsigned int translate_open_flags(int flags)

static void sp_setfsuidgid( uid_t uid, gid_t gid)
{
current->fsuid = uid;
current->fsgid = gid;
current->cred->fsuid = uid;
current->cred->fsgid = gid;

key_fsuid_changed(current);
key_fsgid_changed(current);
Expand Down
28 changes: 14 additions & 14 deletions arch/s390/kernel/compat_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ asmlinkage long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user
{
int retval;

if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
!(retval = put_user(high2lowuid(current->euid), euid)))
retval = put_user(high2lowuid(current->suid), suid);
if (!(retval = put_user(high2lowuid(current->cred->uid), ruid)) &&
!(retval = put_user(high2lowuid(current->cred->euid), euid)))
retval = put_user(high2lowuid(current->cred->suid), suid);

return retval;
}
Expand All @@ -165,9 +165,9 @@ asmlinkage long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user
{
int retval;

if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
!(retval = put_user(high2lowgid(current->egid), egid)))
retval = put_user(high2lowgid(current->sgid), sgid);
if (!(retval = put_user(high2lowgid(current->cred->gid), rgid)) &&
!(retval = put_user(high2lowgid(current->cred->egid), egid)))
retval = put_user(high2lowgid(current->cred->sgid), sgid);

return retval;
}
Expand Down Expand Up @@ -217,20 +217,20 @@ asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist)
if (gidsetsize < 0)
return -EINVAL;

get_group_info(current->group_info);
i = current->group_info->ngroups;
get_group_info(current->cred->group_info);
i = current->cred->group_info->ngroups;
if (gidsetsize) {
if (i > gidsetsize) {
i = -EINVAL;
goto out;
}
if (groups16_to_user(grouplist, current->group_info)) {
if (groups16_to_user(grouplist, current->cred->group_info)) {
i = -EFAULT;
goto out;
}
}
out:
put_group_info(current->group_info);
put_group_info(current->cred->group_info);
return i;
}

Expand Down Expand Up @@ -261,22 +261,22 @@ asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist)

asmlinkage long sys32_getuid16(void)
{
return high2lowuid(current->uid);
return high2lowuid(current->cred->uid);
}

asmlinkage long sys32_geteuid16(void)
{
return high2lowuid(current->euid);
return high2lowuid(current->cred->euid);
}

asmlinkage long sys32_getgid16(void)
{
return high2lowgid(current->gid);
return high2lowgid(current->cred->gid);
}

asmlinkage long sys32_getegid16(void)
{
return high2lowgid(current->egid);
return high2lowgid(current->cred->egid);
}

/*
Expand Down
8 changes: 4 additions & 4 deletions drivers/connector/cn_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,11 @@ void proc_id_connector(struct task_struct *task, int which_id)
ev->event_data.id.process_pid = task->pid;
ev->event_data.id.process_tgid = task->tgid;
if (which_id == PROC_EVENT_UID) {
ev->event_data.id.r.ruid = task->uid;
ev->event_data.id.e.euid = task->euid;
ev->event_data.id.r.ruid = task->cred->uid;
ev->event_data.id.e.euid = task->cred->euid;
} else if (which_id == PROC_EVENT_GID) {
ev->event_data.id.r.rgid = task->gid;
ev->event_data.id.e.egid = task->egid;
ev->event_data.id.r.rgid = task->cred->gid;
ev->event_data.id.e.egid = task->cred->egid;
} else
return;
get_seq(&msg->seq, &ev->cpu);
Expand Down
12 changes: 6 additions & 6 deletions fs/binfmt_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
NEW_AUX_ENT(AT_BASE, interp_load_addr);
NEW_AUX_ENT(AT_FLAGS, 0);
NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
NEW_AUX_ENT(AT_UID, tsk->uid);
NEW_AUX_ENT(AT_EUID, tsk->euid);
NEW_AUX_ENT(AT_GID, tsk->gid);
NEW_AUX_ENT(AT_EGID, tsk->egid);
NEW_AUX_ENT(AT_UID, tsk->cred->uid);
NEW_AUX_ENT(AT_EUID, tsk->cred->euid);
NEW_AUX_ENT(AT_GID, tsk->cred->gid);
NEW_AUX_ENT(AT_EGID, tsk->cred->egid);
NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
NEW_AUX_ENT(AT_EXECFN, bprm->exec);
if (k_platform) {
Expand Down Expand Up @@ -1388,8 +1388,8 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
psinfo->pr_zomb = psinfo->pr_sname == 'Z';
psinfo->pr_nice = task_nice(p);
psinfo->pr_flag = p->flags;
SET_UID(psinfo->pr_uid, p->uid);
SET_GID(psinfo->pr_gid, p->gid);
SET_UID(psinfo->pr_uid, p->cred->uid);
SET_GID(psinfo->pr_gid, p->cred->gid);
strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));

return 0;
Expand Down
12 changes: 6 additions & 6 deletions fs/binfmt_elf_fdpic.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,10 +623,10 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
NEW_AUX_ENT(AT_BASE, interp_params->elfhdr_addr);
NEW_AUX_ENT(AT_FLAGS, 0);
NEW_AUX_ENT(AT_ENTRY, exec_params->entry_addr);
NEW_AUX_ENT(AT_UID, (elf_addr_t) current_uid());
NEW_AUX_ENT(AT_EUID, (elf_addr_t) current_euid());
NEW_AUX_ENT(AT_GID, (elf_addr_t) current_gid());
NEW_AUX_ENT(AT_EGID, (elf_addr_t) current_egid());
NEW_AUX_ENT(AT_UID, (elf_addr_t) current->cred->uid);
NEW_AUX_ENT(AT_EUID, (elf_addr_t) current->cred->euid);
NEW_AUX_ENT(AT_GID, (elf_addr_t) current->cred->gid);
NEW_AUX_ENT(AT_EGID, (elf_addr_t) current->cred->egid);
NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
NEW_AUX_ENT(AT_EXECFN, bprm->exec);

Expand Down Expand Up @@ -1440,8 +1440,8 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
psinfo->pr_zomb = psinfo->pr_sname == 'Z';
psinfo->pr_nice = task_nice(p);
psinfo->pr_flag = p->flags;
SET_UID(psinfo->pr_uid, p->uid);
SET_GID(psinfo->pr_gid, p->gid);
SET_UID(psinfo->pr_uid, p->cred->uid);
SET_GID(psinfo->pr_gid, p->cred->gid);
strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));

return 0;
Expand Down
4 changes: 2 additions & 2 deletions fs/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1738,7 +1738,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
*/
if (get_dumpable(mm) == 2) { /* Setuid core dump mode */
flag = O_EXCL; /* Stop rewrite attacks */
current->fsuid = 0; /* Dump root private */
current->cred->fsuid = 0; /* Dump root private */
}

retval = coredump_wait(exit_code, &core_state);
Expand Down Expand Up @@ -1834,7 +1834,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
if (helper_argv)
argv_free(helper_argv);

current->fsuid = fsuid;
current->cred->fsuid = fsuid;
coredump_finish(mm);
fail:
return retval;
Expand Down
4 changes: 2 additions & 2 deletions fs/fcntl.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,8 @@ static inline int sigio_perm(struct task_struct *p,
struct fown_struct *fown, int sig)
{
return (((fown->euid == 0) ||
(fown->euid == p->suid) || (fown->euid == p->uid) ||
(fown->uid == p->suid) || (fown->uid == p->uid)) &&
(fown->euid == p->cred->suid) || (fown->euid == p->cred->uid) ||
(fown->uid == p->cred->suid) || (fown->uid == p->cred->uid)) &&
!security_file_send_sigiotask(p, fown, sig));
}

Expand Down
4 changes: 2 additions & 2 deletions fs/file_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ struct file *get_empty_filp(void)
INIT_LIST_HEAD(&f->f_u.fu_list);
atomic_long_set(&f->f_count, 1);
rwlock_init(&f->f_owner.lock);
f->f_uid = tsk->fsuid;
f->f_gid = tsk->fsgid;
f->f_uid = tsk->cred->fsuid;
f->f_gid = tsk->cred->fsgid;
eventpoll_init_file(f);
/* f->f_version: 0 */
return f;
Expand Down
12 changes: 6 additions & 6 deletions fs/fuse/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -872,12 +872,12 @@ int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
if (fc->flags & FUSE_ALLOW_OTHER)
return 1;

if (task->euid == fc->user_id &&
task->suid == fc->user_id &&
task->uid == fc->user_id &&
task->egid == fc->group_id &&
task->sgid == fc->group_id &&
task->gid == fc->group_id)
if (task->cred->euid == fc->user_id &&
task->cred->suid == fc->user_id &&
task->cred->uid == fc->user_id &&
task->cred->egid == fc->group_id &&
task->cred->sgid == fc->group_id &&
task->cred->gid == fc->group_id)
return 1;

return 0;
Expand Down
4 changes: 2 additions & 2 deletions fs/hugetlbfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -958,7 +958,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
if (!can_do_hugetlb_shm())
return ERR_PTR(-EPERM);

if (!user_shm_lock(size, current->user))
if (!user_shm_lock(size, current->cred->user))
return ERR_PTR(-ENOMEM);

root = hugetlbfs_vfsmount->mnt_root;
Expand Down Expand Up @@ -998,7 +998,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
out_dentry:
dput(dentry);
out_shm_unlock:
user_shm_unlock(size, current->user);
user_shm_unlock(size, current->cred->user);
return ERR_PTR(error);
}

Expand Down
12 changes: 6 additions & 6 deletions fs/ioprio.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ static int set_task_ioprio(struct task_struct *task, int ioprio)
int err;
struct io_context *ioc;

if (task->uid != current_euid() &&
task->uid != current_uid() && !capable(CAP_SYS_NICE))
if (task->cred->uid != current_euid() &&
task->cred->uid != current_uid() && !capable(CAP_SYS_NICE))
return -EPERM;

err = security_task_setioprio(task, ioprio);
Expand Down Expand Up @@ -123,15 +123,15 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
break;
case IOPRIO_WHO_USER:
if (!who)
user = current->user;
user = current->cred->user;
else
user = find_user(who);

if (!user)
break;

do_each_thread(g, p) {
if (p->uid != who)
if (p->cred->uid != who)
continue;
ret = set_task_ioprio(p, ioprio);
if (ret)
Expand Down Expand Up @@ -216,15 +216,15 @@ asmlinkage long sys_ioprio_get(int which, int who)
break;
case IOPRIO_WHO_USER:
if (!who)
user = current->user;
user = current->cred->user;
else
user = find_user(who);

if (!user)
break;

do_each_thread(g, p) {
if (p->uid != user->uid)
if (p->cred->uid != user->uid)
continue;
tmpio = get_task_ioprio(p);
if (tmpio < 0)
Expand Down
22 changes: 12 additions & 10 deletions fs/nfsd/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)

int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
{
struct cred *act_as = current->cred ;
struct svc_cred cred = rqstp->rq_cred;
int i;
int flags = nfsexp_flags(rqstp, exp);
Expand Down Expand Up @@ -55,25 +56,26 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
get_group_info(cred.cr_group_info);

if (cred.cr_uid != (uid_t) -1)
current->fsuid = cred.cr_uid;
act_as->fsuid = cred.cr_uid;
else
current->fsuid = exp->ex_anon_uid;
act_as->fsuid = exp->ex_anon_uid;
if (cred.cr_gid != (gid_t) -1)
current->fsgid = cred.cr_gid;
act_as->fsgid = cred.cr_gid;
else
current->fsgid = exp->ex_anon_gid;
act_as->fsgid = exp->ex_anon_gid;

if (!cred.cr_group_info)
return -ENOMEM;
ret = set_current_groups(cred.cr_group_info);
ret = set_groups(act_as, cred.cr_group_info);
put_group_info(cred.cr_group_info);
if ((cred.cr_uid)) {
current->cap_effective =
cap_drop_nfsd_set(current->cap_effective);
act_as->cap_effective =
cap_drop_nfsd_set(act_as->cap_effective);
} else {
current->cap_effective =
cap_raise_nfsd_set(current->cap_effective,
current->cap_permitted);
act_as->cap_effective =
cap_raise_nfsd_set(act_as->cap_effective,
act_as->cap_permitted);
}
return ret;
}

Loading

0 comments on commit b6dff3e

Please sign in to comment.