Message ID | 1478812710-17190-3-git-send-email-agruenba@redhat.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
On Thu, Nov 10, 2016 at 4:18 PM, Andreas Gruenbacher <agruenba@redhat.com> wrote: > Pass the file mode of the proc inode to be created to > proc_pid_make_inode. In proc_pid_make_inode, initialize inode->i_mode > before calling security_task_to_inode. This allows selinux to set > isec->sclass right away without introducing "half-initialized" inode > security structs. > > Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> > --- > fs/proc/base.c | 23 +++++++++-------------- > fs/proc/fd.c | 6 ++---- > fs/proc/internal.h | 2 +- > fs/proc/namespaces.c | 3 +-- > security/selinux/hooks.c | 1 + > 5 files changed, 14 insertions(+), 21 deletions(-) Seems reasonable, merged. > diff --git a/fs/proc/base.c b/fs/proc/base.c > index ca651ac..6eae4d0 100644 > --- a/fs/proc/base.c > +++ b/fs/proc/base.c > @@ -1664,7 +1664,8 @@ const struct inode_operations proc_pid_link_inode_operations = { > > /* building an inode */ > > -struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task) > +struct inode *proc_pid_make_inode(struct super_block * sb, > + struct task_struct *task, umode_t mode) > { > struct inode * inode; > struct proc_inode *ei; > @@ -1678,6 +1679,7 @@ struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *t > > /* Common stuff */ > ei = PROC_I(inode); > + inode->i_mode = mode; > inode->i_ino = get_next_ino(); > inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); > inode->i_op = &proc_def_inode_operations; > @@ -2004,7 +2006,9 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, > struct proc_inode *ei; > struct inode *inode; > > - inode = proc_pid_make_inode(dir->i_sb, task); > + inode = proc_pid_make_inode(dir->i_sb, task, S_IFLNK | > + ((mode & FMODE_READ ) ? S_IRUSR : 0) | > + ((mode & FMODE_WRITE) ? S_IWUSR : 0)); > if (!inode) > return -ENOENT; > > @@ -2013,12 +2017,6 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, > > inode->i_op = &proc_map_files_link_inode_operations; > inode->i_size = 64; > - inode->i_mode = S_IFLNK; > - > - if (mode & FMODE_READ) > - inode->i_mode |= S_IRUSR; > - if (mode & FMODE_WRITE) > - inode->i_mode |= S_IWUSR; > > d_set_d_op(dentry, &tid_map_files_dentry_operations); > d_add(dentry, inode); > @@ -2372,12 +2370,11 @@ static int proc_pident_instantiate(struct inode *dir, > struct inode *inode; > struct proc_inode *ei; > > - inode = proc_pid_make_inode(dir->i_sb, task); > + inode = proc_pid_make_inode(dir->i_sb, task, p->mode); > if (!inode) > goto out; > > ei = PROC_I(inode); > - inode->i_mode = p->mode; > if (S_ISDIR(inode->i_mode)) > set_nlink(inode, 2); /* Use getattr to fix if necessary */ > if (p->iop) > @@ -3059,11 +3056,10 @@ static int proc_pid_instantiate(struct inode *dir, > { > struct inode *inode; > > - inode = proc_pid_make_inode(dir->i_sb, task); > + inode = proc_pid_make_inode(dir->i_sb, task, S_IFDIR | S_IRUGO | S_IXUGO); > if (!inode) > goto out; > > - inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; > inode->i_op = &proc_tgid_base_inode_operations; > inode->i_fop = &proc_tgid_base_operations; > inode->i_flags|=S_IMMUTABLE; > @@ -3352,11 +3348,10 @@ static int proc_task_instantiate(struct inode *dir, > struct dentry *dentry, struct task_struct *task, const void *ptr) > { > struct inode *inode; > - inode = proc_pid_make_inode(dir->i_sb, task); > + inode = proc_pid_make_inode(dir->i_sb, task, S_IFDIR | S_IRUGO | S_IXUGO); > > if (!inode) > goto out; > - inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; > inode->i_op = &proc_tid_base_inode_operations; > inode->i_fop = &proc_tid_base_operations; > inode->i_flags|=S_IMMUTABLE; > diff --git a/fs/proc/fd.c b/fs/proc/fd.c > index d21dafe..4274f83 100644 > --- a/fs/proc/fd.c > +++ b/fs/proc/fd.c > @@ -183,14 +183,13 @@ proc_fd_instantiate(struct inode *dir, struct dentry *dentry, > struct proc_inode *ei; > struct inode *inode; > > - inode = proc_pid_make_inode(dir->i_sb, task); > + inode = proc_pid_make_inode(dir->i_sb, task, S_IFLNK); > if (!inode) > goto out; > > ei = PROC_I(inode); > ei->fd = fd; > > - inode->i_mode = S_IFLNK; > inode->i_op = &proc_pid_link_inode_operations; > inode->i_size = 64; > > @@ -322,14 +321,13 @@ proc_fdinfo_instantiate(struct inode *dir, struct dentry *dentry, > struct proc_inode *ei; > struct inode *inode; > > - inode = proc_pid_make_inode(dir->i_sb, task); > + inode = proc_pid_make_inode(dir->i_sb, task, S_IFREG | S_IRUSR); > if (!inode) > goto out; > > ei = PROC_I(inode); > ei->fd = fd; > > - inode->i_mode = S_IFREG | S_IRUSR; > inode->i_fop = &proc_fdinfo_file_operations; > > d_set_d_op(dentry, &tid_fd_dentry_operations); > diff --git a/fs/proc/internal.h b/fs/proc/internal.h > index 5378441..f4494dc 100644 > --- a/fs/proc/internal.h > +++ b/fs/proc/internal.h > @@ -162,7 +162,7 @@ extern int proc_pid_statm(struct seq_file *, struct pid_namespace *, > extern const struct dentry_operations pid_dentry_operations; > extern int pid_getattr(struct vfsmount *, struct dentry *, struct kstat *); > extern int proc_setattr(struct dentry *, struct iattr *); > -extern struct inode *proc_pid_make_inode(struct super_block *, struct task_struct *); > +extern struct inode *proc_pid_make_inode(struct super_block *, struct task_struct *, umode_t); > extern int pid_revalidate(struct dentry *, unsigned int); > extern int pid_delete_dentry(const struct dentry *); > extern int proc_pid_readdir(struct file *, struct dir_context *); > diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c > index 51b8b0a..766f0c6 100644 > --- a/fs/proc/namespaces.c > +++ b/fs/proc/namespaces.c > @@ -92,12 +92,11 @@ static int proc_ns_instantiate(struct inode *dir, > struct inode *inode; > struct proc_inode *ei; > > - inode = proc_pid_make_inode(dir->i_sb, task); > + inode = proc_pid_make_inode(dir->i_sb, task, S_IFLNK | S_IRWXUGO); > if (!inode) > goto out; > > ei = PROC_I(inode); > - inode->i_mode = S_IFLNK|S_IRWXUGO; > inode->i_op = &proc_ns_link_inode_operations; > ei->ns_ops = ns_ops; > > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > index b98ab2a..e4527d9 100644 > --- a/security/selinux/hooks.c > +++ b/security/selinux/hooks.c > @@ -3954,6 +3954,7 @@ static void selinux_task_to_inode(struct task_struct *p, > struct inode_security_struct *isec = inode->i_security; > u32 sid = task_sid(p); > > + isec->sclass = inode_mode_to_security_class(inode->i_mode); > isec->sid = sid; > isec->initialized = LABEL_INITIALIZED; > } > -- > 2.7.4 >
diff --git a/fs/proc/base.c b/fs/proc/base.c index ca651ac..6eae4d0 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1664,7 +1664,8 @@ const struct inode_operations proc_pid_link_inode_operations = { /* building an inode */ -struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *task) +struct inode *proc_pid_make_inode(struct super_block * sb, + struct task_struct *task, umode_t mode) { struct inode * inode; struct proc_inode *ei; @@ -1678,6 +1679,7 @@ struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *t /* Common stuff */ ei = PROC_I(inode); + inode->i_mode = mode; inode->i_ino = get_next_ino(); inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); inode->i_op = &proc_def_inode_operations; @@ -2004,7 +2006,9 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, struct proc_inode *ei; struct inode *inode; - inode = proc_pid_make_inode(dir->i_sb, task); + inode = proc_pid_make_inode(dir->i_sb, task, S_IFLNK | + ((mode & FMODE_READ ) ? S_IRUSR : 0) | + ((mode & FMODE_WRITE) ? S_IWUSR : 0)); if (!inode) return -ENOENT; @@ -2013,12 +2017,6 @@ proc_map_files_instantiate(struct inode *dir, struct dentry *dentry, inode->i_op = &proc_map_files_link_inode_operations; inode->i_size = 64; - inode->i_mode = S_IFLNK; - - if (mode & FMODE_READ) - inode->i_mode |= S_IRUSR; - if (mode & FMODE_WRITE) - inode->i_mode |= S_IWUSR; d_set_d_op(dentry, &tid_map_files_dentry_operations); d_add(dentry, inode); @@ -2372,12 +2370,11 @@ static int proc_pident_instantiate(struct inode *dir, struct inode *inode; struct proc_inode *ei; - inode = proc_pid_make_inode(dir->i_sb, task); + inode = proc_pid_make_inode(dir->i_sb, task, p->mode); if (!inode) goto out; ei = PROC_I(inode); - inode->i_mode = p->mode; if (S_ISDIR(inode->i_mode)) set_nlink(inode, 2); /* Use getattr to fix if necessary */ if (p->iop) @@ -3059,11 +3056,10 @@ static int proc_pid_instantiate(struct inode *dir, { struct inode *inode; - inode = proc_pid_make_inode(dir->i_sb, task); + inode = proc_pid_make_inode(dir->i_sb, task, S_IFDIR | S_IRUGO | S_IXUGO); if (!inode) goto out; - inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; inode->i_op = &proc_tgid_base_inode_operations; inode->i_fop = &proc_tgid_base_operations; inode->i_flags|=S_IMMUTABLE; @@ -3352,11 +3348,10 @@ static int proc_task_instantiate(struct inode *dir, struct dentry *dentry, struct task_struct *task, const void *ptr) { struct inode *inode; - inode = proc_pid_make_inode(dir->i_sb, task); + inode = proc_pid_make_inode(dir->i_sb, task, S_IFDIR | S_IRUGO | S_IXUGO); if (!inode) goto out; - inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; inode->i_op = &proc_tid_base_inode_operations; inode->i_fop = &proc_tid_base_operations; inode->i_flags|=S_IMMUTABLE; diff --git a/fs/proc/fd.c b/fs/proc/fd.c index d21dafe..4274f83 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c @@ -183,14 +183,13 @@ proc_fd_instantiate(struct inode *dir, struct dentry *dentry, struct proc_inode *ei; struct inode *inode; - inode = proc_pid_make_inode(dir->i_sb, task); + inode = proc_pid_make_inode(dir->i_sb, task, S_IFLNK); if (!inode) goto out; ei = PROC_I(inode); ei->fd = fd; - inode->i_mode = S_IFLNK; inode->i_op = &proc_pid_link_inode_operations; inode->i_size = 64; @@ -322,14 +321,13 @@ proc_fdinfo_instantiate(struct inode *dir, struct dentry *dentry, struct proc_inode *ei; struct inode *inode; - inode = proc_pid_make_inode(dir->i_sb, task); + inode = proc_pid_make_inode(dir->i_sb, task, S_IFREG | S_IRUSR); if (!inode) goto out; ei = PROC_I(inode); ei->fd = fd; - inode->i_mode = S_IFREG | S_IRUSR; inode->i_fop = &proc_fdinfo_file_operations; d_set_d_op(dentry, &tid_fd_dentry_operations); diff --git a/fs/proc/internal.h b/fs/proc/internal.h index 5378441..f4494dc 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -162,7 +162,7 @@ extern int proc_pid_statm(struct seq_file *, struct pid_namespace *, extern const struct dentry_operations pid_dentry_operations; extern int pid_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern int proc_setattr(struct dentry *, struct iattr *); -extern struct inode *proc_pid_make_inode(struct super_block *, struct task_struct *); +extern struct inode *proc_pid_make_inode(struct super_block *, struct task_struct *, umode_t); extern int pid_revalidate(struct dentry *, unsigned int); extern int pid_delete_dentry(const struct dentry *); extern int proc_pid_readdir(struct file *, struct dir_context *); diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index 51b8b0a..766f0c6 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c @@ -92,12 +92,11 @@ static int proc_ns_instantiate(struct inode *dir, struct inode *inode; struct proc_inode *ei; - inode = proc_pid_make_inode(dir->i_sb, task); + inode = proc_pid_make_inode(dir->i_sb, task, S_IFLNK | S_IRWXUGO); if (!inode) goto out; ei = PROC_I(inode); - inode->i_mode = S_IFLNK|S_IRWXUGO; inode->i_op = &proc_ns_link_inode_operations; ei->ns_ops = ns_ops; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b98ab2a..e4527d9 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3954,6 +3954,7 @@ static void selinux_task_to_inode(struct task_struct *p, struct inode_security_struct *isec = inode->i_security; u32 sid = task_sid(p); + isec->sclass = inode_mode_to_security_class(inode->i_mode); isec->sid = sid; isec->initialized = LABEL_INITIALIZED; }
Pass the file mode of the proc inode to be created to proc_pid_make_inode. In proc_pid_make_inode, initialize inode->i_mode before calling security_task_to_inode. This allows selinux to set isec->sclass right away without introducing "half-initialized" inode security structs. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> --- fs/proc/base.c | 23 +++++++++-------------- fs/proc/fd.c | 6 ++---- fs/proc/internal.h | 2 +- fs/proc/namespaces.c | 3 +-- security/selinux/hooks.c | 1 + 5 files changed, 14 insertions(+), 21 deletions(-)