From 233e70f4228e78eb2f80dc6650f65d3ae3dbf17c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 31 Oct 2008 23:28:30 +0000 Subject: saner FASYNC handling on file close As it is, all instances of ->release() for files that have ->fasync() need to remember to evict file from fasync lists; forgetting that creates a hole and we actually have a bunch that *does* forget. So let's keep our lives simple - let __fput() check FASYNC in file->f_flags and call ->fasync() there if it's been set. And lose that crap in ->release() instances - leaving it there is still valid, but we don't have to bother anymore. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- fs/pipe.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'fs/pipe.c') diff --git a/fs/pipe.c b/fs/pipe.c index fcba6542b8d..7aea8b89baa 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -717,14 +717,12 @@ pipe_rdwr_fasync(int fd, struct file *filp, int on) static int pipe_read_release(struct inode *inode, struct file *filp) { - pipe_read_fasync(-1, filp, 0); return pipe_release(inode, 1, 0); } static int pipe_write_release(struct inode *inode, struct file *filp) { - pipe_write_fasync(-1, filp, 0); return pipe_release(inode, 0, 1); } @@ -733,7 +731,6 @@ pipe_rdwr_release(struct inode *inode, struct file *filp) { int decr, decw; - pipe_rdwr_fasync(-1, filp, 0); decr = (filp->f_mode & FMODE_READ) != 0; decw = (filp->f_mode & FMODE_WRITE) != 0; return pipe_release(inode, decr, decw); -- cgit v1.2.3-70-g09d2 From da9592edebceeba1b9301beafe80ec8b9c2db0ce Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 14 Nov 2008 10:39:05 +1100 Subject: CRED: Wrap task credential accesses in the filesystem 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 Reviewed-by: James Morris Acked-by: Serge Hallyn Cc: Al Viro Signed-off-by: James Morris --- fs/anon_inodes.c | 4 ++-- fs/attr.c | 4 ++-- fs/binfmt_elf_fdpic.c | 8 ++++---- fs/dquot.c | 4 ++-- fs/exec.c | 18 +++++++++--------- fs/fcntl.c | 2 +- fs/inotify_user.c | 2 +- fs/ioprio.c | 4 ++-- fs/locks.c | 2 +- fs/namei.c | 10 ++++++---- fs/namespace.c | 2 +- fs/pipe.c | 4 ++-- fs/posix_acl.c | 4 ++-- fs/quota.c | 4 ++-- include/linux/fs.h | 2 +- 15 files changed, 38 insertions(+), 36 deletions(-) (limited to 'fs/pipe.c') diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 3662dd44896..c16d9be1b01 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c @@ -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; } diff --git a/fs/attr.c b/fs/attr.c index 7a83819f6ba..f4360192a93 100644 --- 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; diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 5b5424cb339..488584c8751 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -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); diff --git a/fs/dquot.c b/fs/dquot.c index 5e95261005b..c237ccc8581 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -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); diff --git a/fs/exec.c b/fs/exec.c index 4e834f16d9d..604834f3b20 100644 --- 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; diff --git a/fs/fcntl.c b/fs/fcntl.c index ac4f7db9f13..bf049a805e5 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -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); diff --git a/fs/inotify_user.c b/fs/inotify_user.c index d367e9b9286..e2425bbd871 100644 --- a/fs/inotify_user.c +++ b/fs/inotify_user.c @@ -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; diff --git a/fs/ioprio.c b/fs/ioprio.c index da3cc460d4d..68d2cd80711 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c @@ -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); diff --git a/fs/locks.c b/fs/locks.c index 09062e3ff10..46a2e12f7d4 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -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; diff --git a/fs/namei.c b/fs/namei.c index 09ce58e49e7..42d7b760693 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -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); } diff --git a/fs/namespace.c b/fs/namespace.c index cce46702d33..d8bc2c4704a 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -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)) diff --git a/fs/pipe.c b/fs/pipe.c index 7aea8b89baa..aaf797bd57b 100644 --- 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; diff --git a/fs/posix_acl.c b/fs/posix_acl.c index aec931e0997..39df95a0ec2 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -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: diff --git a/fs/quota.c b/fs/quota.c index 7f4386ebc23..b7fe44e0161 100644 --- a/fs/quota.c +++ b/fs/quota.c @@ -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; diff --git a/include/linux/fs.h b/include/linux/fs.h index 0dcdd9458f4..b3d404aaabe 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1193,7 +1193,7 @@ enum { #define has_fs_excl() atomic_read(¤t->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 *); -- cgit v1.2.3-70-g09d2