Matthew Wilcox <willy@xxxxxxxxxxxxx> writes: > On Thu, Dec 03, 2020 at 04:02:12PM -0800, Stephen Brennan wrote: >> -void pid_update_inode(struct task_struct *task, struct inode *inode) >> +static int do_pid_update_inode(struct task_struct *task, struct inode *inode, >> + unsigned int flags) > > I'm really nitpicking here, but this function only _updates_ the inode > if flags says it should. So I was thinking something like this > (compile tested only). > > I'd really appreocate feedback from someone like Casey or Stephen on > what they need for their security modules. Just so we don't have security module questions confusing things can we please make this a 2 patch series? With the first patch removing security_task_to_inode? The justification for the removal is that all security_task_to_inode appears to care about is the file type bits in inode->i_mode. Something that never changes. Having this in a separate patch would make that logical change easier to verify. Eric > > diff --git a/fs/proc/base.c b/fs/proc/base.c > index b362523a9829..771f330bfce7 100644 > --- a/fs/proc/base.c > +++ b/fs/proc/base.c > @@ -1968,6 +1968,25 @@ void pid_update_inode(struct task_struct *task, struct inode *inode) > security_task_to_inode(task, inode); > } > > +/* See if we can avoid the above call. Assumes RCU lock held */ > +static bool inode_needs_pid_update(struct task_struct *task, > + const struct inode *inode) > +{ > + kuid_t uid; > + kgid_t gid; > + > + if (inode->i_mode & (S_ISUID | S_ISGID)) > + return true; > + task_dump_owner(task, inode->i_mode, &uid, &gid); > + if (!uid_eq(uid, inode->i_uid) || !gid_eq(gid, inode->i_gid)) > + return true; > + /* > + * XXX: Do we need to call the security system here to see if > + * there's a pending update? > + */ > + return false; > +} > + > /* > * Rewrite the inode's ownerships here because the owning task may have > * performed a setuid(), etc. > @@ -1978,8 +1997,15 @@ static int pid_revalidate(struct dentry *dentry, unsigned int flags) > struct inode *inode; > struct task_struct *task; > > - if (flags & LOOKUP_RCU) > + if (flags & LOOKUP_RCU) { > + inode = d_inode_rcu(dentry); > + task = pid_task(proc_pid(inode), PIDTYPE_PID); > + if (!task) > + return 0; > + if (!inode_needs_pid_update(task, inode)) > + return 1; > return -ECHILD; > + } > > inode = d_inode(dentry); > task = get_proc_task(inode);