CRED: Wrap task credential accesses in the filesystem subsystem
David Howells [Thu, 13 Nov 2008 23:39:05 +0000 (10:39 +1100)]
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>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: James Morris <jmorris@namei.org>

15 files changed:
fs/anon_inodes.c
fs/attr.c
fs/binfmt_elf_fdpic.c
fs/dquot.c
fs/exec.c
fs/fcntl.c
fs/inotify_user.c
fs/ioprio.c
fs/locks.c
fs/namei.c
fs/namespace.c
fs/pipe.c
fs/posix_acl.c
fs/quota.c
include/linux/fs.h

index 3662dd4..c16d9be 100644 (file)
@@ -154,8 +154,8 @@ static struct inode *anon_inode_mkinode(void)
         */
        inode->i_state = I_DIRTY;
        inode->i_mode = S_IRUSR | S_IWUSR;
-       inode->i_uid = current->fsuid;
-       inode->i_gid = current->fsgid;
+       inode->i_uid = current_fsuid();
+       inode->i_gid = current_fsgid();
        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
        return inode;
 }
index 7a83819..f436019 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -29,13 +29,13 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
 
        /* Make sure a caller can chown. */
        if ((ia_valid & ATTR_UID) &&
-           (current->fsuid != inode->i_uid ||
+           (current_fsuid() != inode->i_uid ||
             attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN))
                goto error;
 
        /* Make sure caller can chgrp. */
        if ((ia_valid & ATTR_GID) &&
-           (current->fsuid != inode->i_uid ||
+           (current_fsuid() != inode->i_uid ||
            (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) &&
            !capable(CAP_CHOWN))
                goto error;
index 5b5424c..488584c 100644 (file)
@@ -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_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_SECURE,  security_bprm_secureexec(bprm));
        NEW_AUX_ENT(AT_EXECFN,  bprm->exec);
 
index 5e95261..c237ccc 100644 (file)
@@ -874,7 +874,7 @@ static inline int need_print_warning(struct dquot *dquot)
 
        switch (dquot->dq_type) {
                case USRQUOTA:
-                       return current->fsuid == dquot->dq_id;
+                       return current_fsuid() == dquot->dq_id;
                case GRPQUOTA:
                        return in_group_p(dquot->dq_id);
        }
@@ -981,7 +981,7 @@ static void send_warning(const struct dquot *dquot, const char warntype)
                MINOR(dquot->dq_sb->s_dev));
        if (ret)
                goto attr_err_out;
-       ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current->user->uid);
+       ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid());
        if (ret)
                goto attr_err_out;
        genlmsg_end(skb, msg_head);
index 4e834f1..604834f 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -980,7 +980,7 @@ int flush_old_exec(struct linux_binprm * bprm)
        /* This is the point of no return */
        current->sas_ss_sp = current->sas_ss_size = 0;
 
-       if (current->euid == current->uid && current->egid == current->gid)
+       if (current_euid() == current_uid() && current_egid() == current_gid())
                set_dumpable(current->mm, 1);
        else
                set_dumpable(current->mm, suid_dumpable);
@@ -1007,7 +1007,7 @@ int flush_old_exec(struct linux_binprm * bprm)
         */
        current->mm->task_size = TASK_SIZE;
 
-       if (bprm->e_uid != current->euid || bprm->e_gid != current->egid) {
+       if (bprm->e_uid != current_euid() || bprm->e_gid != current_egid()) {
                suid_keys(current);
                set_dumpable(current->mm, suid_dumpable);
                current->pdeath_signal = 0;
@@ -1047,8 +1047,8 @@ int prepare_binprm(struct linux_binprm *bprm)
        if (bprm->file->f_op == NULL)
                return -EACCES;
 
-       bprm->e_uid = current->euid;
-       bprm->e_gid = current->egid;
+       bprm->e_uid = current_euid();
+       bprm->e_gid = current_egid();
 
        if(!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) {
                /* Set-uid? */
@@ -1096,7 +1096,7 @@ void compute_creds(struct linux_binprm *bprm)
 {
        int unsafe;
 
-       if (bprm->e_uid != current->uid) {
+       if (bprm->e_uid != current_uid()) {
                suid_keys(current);
                current->pdeath_signal = 0;
        }
@@ -1424,7 +1424,7 @@ static int format_corename(char *corename, long signr)
                        /* uid */
                        case 'u':
                                rc = snprintf(out_ptr, out_end - out_ptr,
-                                             "%d", current->uid);
+                                             "%d", current_uid());
                                if (rc > out_end - out_ptr)
                                        goto out;
                                out_ptr += rc;
@@ -1432,7 +1432,7 @@ static int format_corename(char *corename, long signr)
                        /* gid */
                        case 'g':
                                rc = snprintf(out_ptr, out_end - out_ptr,
-                                             "%d", current->gid);
+                                             "%d", current_gid());
                                if (rc > out_end - out_ptr)
                                        goto out;
                                out_ptr += rc;
@@ -1709,7 +1709,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
        struct inode * inode;
        struct file * file;
        int retval = 0;
-       int fsuid = current->fsuid;
+       int fsuid = current_fsuid();
        int flag = 0;
        int ispipe = 0;
        unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
@@ -1815,7 +1815,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
         * Dont allow local users get cute and trick others to coredump
         * into their pre-created files:
         */
-       if (inode->i_uid != current->fsuid)
+       if (inode->i_uid != current_fsuid())
                goto close_fail;
        if (!file->f_op)
                goto close_fail;
index ac4f7db..bf049a8 100644 (file)
@@ -211,7 +211,7 @@ int __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
        if (err)
                return err;
 
-       f_modown(filp, pid, type, current->uid, current->euid, force);
+       f_modown(filp, pid, type, current_uid(), current_euid(), force);
        return 0;
 }
 EXPORT_SYMBOL(__f_setown);
index d367e9b..e2425bb 100644 (file)
@@ -601,7 +601,7 @@ asmlinkage long sys_inotify_init1(int flags)
                goto out_put_fd;
        }
 
-       user = get_uid(current->user);
+       user = get_current_user();
        if (unlikely(atomic_read(&user->inotify_devs) >=
                        inotify_max_user_instances)) {
                ret = -EMFILE;
index da3cc46..68d2cd8 100644 (file)
@@ -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->uid != current_euid() &&
+           task->uid != current_uid() && !capable(CAP_SYS_NICE))
                return -EPERM;
 
        err = security_task_setioprio(task, ioprio);
index 09062e3..46a2e12 100644 (file)
@@ -1349,7 +1349,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
        struct inode *inode = dentry->d_inode;
        int error, rdlease_count = 0, wrlease_count = 0;
 
-       if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE))
+       if ((current_fsuid() != inode->i_uid) && !capable(CAP_LEASE))
                return -EACCES;
        if (!S_ISREG(inode->i_mode))
                return -EINVAL;
index 09ce58e..42d7b76 100644 (file)
@@ -186,7 +186,7 @@ int generic_permission(struct inode *inode, int mask,
 
        mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
 
-       if (current->fsuid == inode->i_uid)
+       if (current_fsuid() == inode->i_uid)
                mode >>= 6;
        else {
                if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) {
@@ -441,7 +441,7 @@ static int exec_permission_lite(struct inode *inode)
        if (inode->i_op && inode->i_op->permission)
                return -EAGAIN;
 
-       if (current->fsuid == inode->i_uid)
+       if (current_fsuid() == inode->i_uid)
                mode >>= 6;
        else if (in_group_p(inode->i_gid))
                mode >>= 3;
@@ -1334,11 +1334,13 @@ static int user_path_parent(int dfd, const char __user *path,
  */
 static inline int check_sticky(struct inode *dir, struct inode *inode)
 {
+       uid_t fsuid = current_fsuid();
+
        if (!(dir->i_mode & S_ISVTX))
                return 0;
-       if (inode->i_uid == current->fsuid)
+       if (inode->i_uid == fsuid)
                return 0;
-       if (dir->i_uid == current->fsuid)
+       if (dir->i_uid == fsuid)
                return 0;
        return !capable(CAP_FOWNER);
 }
index cce4670..d8bc2c4 100644 (file)
@@ -1176,7 +1176,7 @@ static int mount_is_safe(struct path *path)
        if (S_ISLNK(path->dentry->d_inode->i_mode))
                return -EPERM;
        if (path->dentry->d_inode->i_mode & S_ISVTX) {
-               if (current->uid != path->dentry->d_inode->i_uid)
+               if (current_uid() != path->dentry->d_inode->i_uid)
                        return -EPERM;
        }
        if (inode_permission(path->dentry->d_inode, MAY_WRITE))
index 7aea8b8..aaf797b 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -899,8 +899,8 @@ static struct inode * get_pipe_inode(void)
         */
        inode->i_state = I_DIRTY;
        inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR;
-       inode->i_uid = current->fsuid;
-       inode->i_gid = current->fsgid;
+       inode->i_uid = current_fsuid();
+       inode->i_gid = current_fsgid();
        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 
        return inode;
index aec931e..39df95a 100644 (file)
@@ -217,11 +217,11 @@ posix_acl_permission(struct inode *inode, const struct posix_acl *acl, int want)
                 switch(pa->e_tag) {
                         case ACL_USER_OBJ:
                                /* (May have been checked already) */
-                                if (inode->i_uid == current->fsuid)
+                               if (inode->i_uid == current_fsuid())
                                         goto check_perm;
                                 break;
                         case ACL_USER:
-                                if (pa->e_id == current->fsuid)
+                               if (pa->e_id == current_fsuid())
                                         goto mask;
                                break;
                         case ACL_GROUP_OBJ:
index 7f4386e..b7fe44e 100644 (file)
@@ -79,7 +79,7 @@ static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid
 
        /* Check privileges */
        if (cmd == Q_GETQUOTA) {
-               if (((type == USRQUOTA && current->euid != id) ||
+               if (((type == USRQUOTA && current_euid() != id) ||
                     (type == GRPQUOTA && !in_egroup_p(id))) &&
                    !capable(CAP_SYS_ADMIN))
                        return -EPERM;
@@ -130,7 +130,7 @@ static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t i
 
        /* Check privileges */
        if (cmd == Q_XGETQUOTA) {
-               if (((type == XQM_USRQUOTA && current->euid != id) ||
+               if (((type == XQM_USRQUOTA && current_euid() != id) ||
                     (type == XQM_GRPQUOTA && !in_egroup_p(id))) &&
                     !capable(CAP_SYS_ADMIN))
                        return -EPERM;
index 0dcdd94..b3d404a 100644 (file)
@@ -1193,7 +1193,7 @@ enum {
 #define has_fs_excl() atomic_read(&current->fs_excl)
 
 #define is_owner_or_cap(inode) \
-       ((current->fsuid == (inode)->i_uid) || capable(CAP_FOWNER))
+       ((current_fsuid() == (inode)->i_uid) || capable(CAP_FOWNER))
 
 /* not quite ready to be deprecated, but... */
 extern void lock_super(struct super_block *);