History

proc: proc_pid_ns takes super_block as an argument

syzbot found that touch /proc/testfile causes NULL pointer dereference at tomoyo_get_local_path() because inode of the dentry is NULL. Before c59f415a7cb6, Tomoyo received pid_ns from proc's s_fs_info directly. Since proc_pid_ns() can only work with inode, using it in the tomoyo_get_local_path() was wrong. To avoid creating more functions for getting proc_ns, change the argument type of the proc_pid_ns() function. Then, Tomoyo can use the existing super_block to get pid_ns.

Alexey Gladkov committed 6 years ago

Commit 9d78ede1 parent 2dd80839 files · +15 −15Browse files

Unified · Split

9 files
  1. fs/locks.c +2 −2
  2. fs/proc/array.c +1 −1
  3. fs/proc/base.c +5 −5
  4. fs/proc/self.c +1 −1
  5. fs/proc/thread_self.c +1 −1
  6. include/linux/proc_fs.h +2 −2
  7. kernel/fork.c +1 −1
  8. net/ipv6/ip6_flowlabel.c +1 −1
  9. security/tomoyo/realpath.c +1 −1
fs/locks.c+2−2
@@ -2823,7 +2823,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl, · 2822 unmodified lines
2823{2823{
2824 struct inode *inode = NULL;2824 struct inode *inode = NULL;
2825 unsigned int fl_pid;2825 unsigned int fl_pid;
2826 struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file));2826 struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file)->i_sb);
2827 2827
2828 fl_pid = locks_translate_pid(fl, proc_pidns);2828 fl_pid = locks_translate_pid(fl, proc_pidns);
2829 /*2829 /*
@@ -2901,7 +2901,7 @@ static int locks_show(struct seq_file *f, void *v) · 71 unmodified lines
2901{2901{
2902 struct locks_iterator *iter = f->private;2902 struct locks_iterator *iter = f->private;
2903 struct file_lock *fl, *bfl;2903 struct file_lock *fl, *bfl;
2904 struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file));2904 struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file)->i_sb);
2905 2905
2906 fl = hlist_entry(v, struct file_lock, fl_link);2906 fl = hlist_entry(v, struct file_lock, fl_link);
2907 2907
fs/proc/array.c+1−1
@@ -728,7 +728,7 @@ static int children_seq_show(struct seq_file *seq, void *v) · 727 unmodified lines
728{728{
729 struct inode *inode = file_inode(seq->file);729 struct inode *inode = file_inode(seq->file);
730 730
731 seq_printf(seq, "%d ", pid_nr_ns(v, proc_pid_ns(inode)));731 seq_printf(seq, "%d ", pid_nr_ns(v, proc_pid_ns(inode->i_sb)));
732 return 0;732 return 0;
733}733}
734 734
fs/proc/base.c+5−5
@@ -754,7 +754,7 @@ static const struct inode_operations proc_def_inode_operations = { · 753 unmodified lines
754static int proc_single_show(struct seq_file *m, void *v)754static int proc_single_show(struct seq_file *m, void *v)
755{755{
756 struct inode *inode = m->private;756 struct inode *inode = m->private;
757 struct pid_namespace *ns = proc_pid_ns(inode);757 struct pid_namespace *ns = proc_pid_ns(inode->i_sb);
758 struct pid *pid = proc_pid(inode);758 struct pid *pid = proc_pid(inode);
759 struct task_struct *task;759 struct task_struct *task;
760 int ret;760 int ret;
@@ -1423,7 +1423,7 @@ static const struct file_operations proc_fail_nth_operations = { · 662 unmodified lines
1423static int sched_show(struct seq_file *m, void *v)1423static int sched_show(struct seq_file *m, void *v)
1424{1424{
1425 struct inode *inode = m->private;1425 struct inode *inode = m->private;
1426 struct pid_namespace *ns = proc_pid_ns(inode);1426 struct pid_namespace *ns = proc_pid_ns(inode->i_sb);
1427 struct task_struct *p;1427 struct task_struct *p;
1428 1428
1429 p = get_proc_task(inode);1429 p = get_proc_task(inode);
@@ -2466,7 +2466,7 @@ static int proc_timers_open(struct inode *inode, struct file *file) · 1036 unmodified lines
2466 return -ENOMEM;2466 return -ENOMEM;
2467 2467
2468 tp->pid = proc_pid(inode);2468 tp->pid = proc_pid(inode);
2469 tp->ns = proc_pid_ns(inode);2469 tp->ns = proc_pid_ns(inode->i_sb);
2470 return 0;2470 return 0;
2471}2471}
2472 2472
@@ -3377,7 +3377,7 @@ int proc_pid_readdir(struct file *file, struct dir_context *ctx) · 904 unmodified lines
3377{3377{
3378 struct tgid_iter iter;3378 struct tgid_iter iter;
3379 struct proc_fs_info *fs_info = proc_sb_info(file_inode(file)->i_sb);3379 struct proc_fs_info *fs_info = proc_sb_info(file_inode(file)->i_sb);
3380 struct pid_namespace *ns = proc_pid_ns(file_inode(file));3380 struct pid_namespace *ns = proc_pid_ns(file_inode(file)->i_sb);
3381 loff_t pos = ctx->pos;3381 loff_t pos = ctx->pos;
3382 3382
3383 if (pos >= PID_MAX_LIMIT + TGID_OFFSET)3383 if (pos >= PID_MAX_LIMIT + TGID_OFFSET)
@@ -3730,7 +3730,7 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx) · 346 unmodified lines
3730 /* f_version caches the tgid value that the last readdir call couldn't3730 /* f_version caches the tgid value that the last readdir call couldn't
3731 * return. lseek aka telldir automagically resets f_version to 0.3731 * return. lseek aka telldir automagically resets f_version to 0.
3732 */3732 */
3733 ns = proc_pid_ns(inode);3733 ns = proc_pid_ns(inode->i_sb);
3734 tid = (int)file->f_version;3734 tid = (int)file->f_version;
3735 file->f_version = 0;3735 file->f_version = 0;
3736 for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns);3736 for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns);
fs/proc/self.c+1−1
@@ -12,7 +12,7 @@ static const char *proc_self_get_link(struct dentry *dentry, · 11 unmodified lines
12 struct inode *inode,12 struct inode *inode,
13 struct delayed_call *done)13 struct delayed_call *done)
14{14{
15 struct pid_namespace *ns = proc_pid_ns(inode);15 struct pid_namespace *ns = proc_pid_ns(inode->i_sb);
16 pid_t tgid = task_tgid_nr_ns(current, ns);16 pid_t tgid = task_tgid_nr_ns(current, ns);
17 char *name;17 char *name;
18 18
fs/proc/thread_self.c+1−1
@@ -12,7 +12,7 @@ static const char *proc_thread_self_get_link(struct dentry *dentry, · 11 unmodified lines
12 struct inode *inode,12 struct inode *inode,
13 struct delayed_call *done)13 struct delayed_call *done)
14{14{
15 struct pid_namespace *ns = proc_pid_ns(inode);15 struct pid_namespace *ns = proc_pid_ns(inode->i_sb);
16 pid_t tgid = task_tgid_nr_ns(current, ns);16 pid_t tgid = task_tgid_nr_ns(current, ns);
17 pid_t pid = task_pid_nr_ns(current, ns);17 pid_t pid = task_pid_nr_ns(current, ns);
18 char *name;18 char *name;
include/linux/proc_fs.h+2−2
@@ -202,9 +202,9 @@ int open_related_ns(struct ns_common *ns, · 201 unmodified lines
202 struct ns_common *(*get_ns)(struct ns_common *ns));202 struct ns_common *(*get_ns)(struct ns_common *ns));
203 203
204/* get the associated pid namespace for a file in procfs */204/* get the associated pid namespace for a file in procfs */
205static inline struct pid_namespace *proc_pid_ns(const struct inode *inode)205static inline struct pid_namespace *proc_pid_ns(struct super_block *sb)
206{206{
207 return proc_sb_info(inode->i_sb)->pid_ns;207 return proc_sb_info(sb)->pid_ns;
208}208}
209 209
210#endif /* _LINUX_PROC_FS_H */210#endif /* _LINUX_PROC_FS_H */
kernel/fork.c+1−1
@@ -1745,7 +1745,7 @@ static void pidfd_show_fdinfo(struct seq_file *m, struct file *f) · 1744 unmodified lines
1745 pid_t nr = -1;1745 pid_t nr = -1;
1746 1746
1747 if (likely(pid_has_task(pid, PIDTYPE_PID))) {1747 if (likely(pid_has_task(pid, PIDTYPE_PID))) {
1748 ns = proc_pid_ns(file_inode(m->file));1748 ns = proc_pid_ns(file_inode(m->file)->i_sb);
1749 nr = pid_nr_ns(pid, ns);1749 nr = pid_nr_ns(pid, ns);
1750 }1750 }
1751 1751
net/ipv6/ip6_flowlabel.c+1−1
@@ -779,7 +779,7 @@ static void *ip6fl_seq_start(struct seq_file *seq, loff_t *pos) · 778 unmodified lines
779{779{
780 struct ip6fl_iter_state *state = ip6fl_seq_private(seq);780 struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
781 781
782 state->pid_ns = proc_pid_ns(file_inode(seq->file));782 state->pid_ns = proc_pid_ns(file_inode(seq->file)->i_sb);
783 783
784 rcu_read_lock_bh();784 rcu_read_lock_bh();
785 return *pos ? ip6fl_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;785 return *pos ? ip6fl_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
security/tomoyo/realpath.c+1−1
@@ -162,7 +162,7 @@ static char *tomoyo_get_local_path(struct dentry *dentry, char * const buffer, · 161 unmodified lines
162 if (sb->s_magic == PROC_SUPER_MAGIC && *pos == '/') {162 if (sb->s_magic == PROC_SUPER_MAGIC && *pos == '/') {
163 char *ep;163 char *ep;
164 const pid_t pid = (pid_t) simple_strtoul(pos + 1, &ep, 10);164 const pid_t pid = (pid_t) simple_strtoul(pos + 1, &ep, 10);
165 struct pid_namespace *proc_pidns = proc_pid_ns(d_inode(dentry));165 struct pid_namespace *proc_pidns = proc_pid_ns(sb);
166 166
167 if (*ep == '/' && pid && pid ==167 if (*ep == '/' && pid && pid ==
168 task_tgid_nr_ns(current, proc_pidns)) {168 task_tgid_nr_ns(current, proc_pidns)) {