diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-08-21 22:32:06 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-26 21:09:59 -0400 |
commit | c3c073f808b22dfae15ef8412b6f7b998644139a (patch) | |
tree | 3369bcbe414738d90e6ccfe257f6ce3e72f6a5ae /drivers/tty | |
parent | ad47bd7252bf402fe7dba92f5240b5ed16832ae7 (diff) |
new helper: iterate_fd()
iterates through the opened files in given descriptor table,
calling a supplied function; we stop once non-zero is returned.
Callback gets struct file *, descriptor number and const void *
argument passed to iterator. It is called with files->file_lock
held, so it is not allowed to block.
tty_io, netprio_cgroup and selinux flush_unauthorized_files()
converted to its use.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/tty_io.c | 36 |
1 files changed, 13 insertions, 23 deletions
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b425c79675ad..71d95cfbabec 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -2791,6 +2791,13 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, | |||
2791 | } | 2791 | } |
2792 | #endif | 2792 | #endif |
2793 | 2793 | ||
2794 | static int this_tty(const void *t, struct file *file, unsigned fd) | ||
2795 | { | ||
2796 | if (likely(file->f_op->read != tty_read)) | ||
2797 | return 0; | ||
2798 | return file_tty(file) != t ? 0 : fd + 1; | ||
2799 | } | ||
2800 | |||
2794 | /* | 2801 | /* |
2795 | * This implements the "Secure Attention Key" --- the idea is to | 2802 | * This implements the "Secure Attention Key" --- the idea is to |
2796 | * prevent trojan horses by killing all processes associated with this | 2803 | * prevent trojan horses by killing all processes associated with this |
@@ -2818,8 +2825,6 @@ void __do_SAK(struct tty_struct *tty) | |||
2818 | struct task_struct *g, *p; | 2825 | struct task_struct *g, *p; |
2819 | struct pid *session; | 2826 | struct pid *session; |
2820 | int i; | 2827 | int i; |
2821 | struct file *filp; | ||
2822 | struct fdtable *fdt; | ||
2823 | 2828 | ||
2824 | if (!tty) | 2829 | if (!tty) |
2825 | return; | 2830 | return; |
@@ -2849,27 +2854,12 @@ void __do_SAK(struct tty_struct *tty) | |||
2849 | continue; | 2854 | continue; |
2850 | } | 2855 | } |
2851 | task_lock(p); | 2856 | task_lock(p); |
2852 | if (p->files) { | 2857 | i = iterate_fd(p->files, 0, this_tty, tty); |
2853 | /* | 2858 | if (i != 0) { |
2854 | * We don't take a ref to the file, so we must | 2859 | printk(KERN_NOTICE "SAK: killed process %d" |
2855 | * hold ->file_lock instead. | 2860 | " (%s): fd#%d opened to the tty\n", |
2856 | */ | 2861 | task_pid_nr(p), p->comm, i - 1); |
2857 | spin_lock(&p->files->file_lock); | 2862 | force_sig(SIGKILL, p); |
2858 | fdt = files_fdtable(p->files); | ||
2859 | for (i = 0; i < fdt->max_fds; i++) { | ||
2860 | filp = fcheck_files(p->files, i); | ||
2861 | if (!filp) | ||
2862 | continue; | ||
2863 | if (filp->f_op->read == tty_read && | ||
2864 | file_tty(filp) == tty) { | ||
2865 | printk(KERN_NOTICE "SAK: killed process %d" | ||
2866 | " (%s): fd#%d opened to the tty\n", | ||
2867 | task_pid_nr(p), p->comm, i); | ||
2868 | force_sig(SIGKILL, p); | ||
2869 | break; | ||
2870 | } | ||
2871 | } | ||
2872 | spin_unlock(&p->files->file_lock); | ||
2873 | } | 2863 | } |
2874 | task_unlock(p); | 2864 | task_unlock(p); |
2875 | } while_each_thread(g, p); | 2865 | } while_each_thread(g, p); |