aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/pty.c6
-rw-r--r--drivers/char/tty_io.c84
-rw-r--r--fs/internal.h2
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/tty.h8
-rw-r--r--security/selinux/hooks.c5
6 files changed, 69 insertions, 38 deletions
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 2c64faa8efa4..c350d01716bd 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -675,12 +675,8 @@ static int ptmx_open(struct inode *inode, struct file *filp)
675 } 675 }
676 676
677 set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ 677 set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
678 filp->private_data = tty;
679 678
680 file_sb_list_del(filp); /* __dentry_open has put it on the sb list */ 679 tty_add_file(tty, filp);
681 spin_lock(&tty_files_lock);
682 list_add(&filp->f_u.fu_list, &tty->tty_files);
683 spin_unlock(&tty_files_lock);
684 680
685 retval = devpts_pty_new(inode, tty->link); 681 retval = devpts_pty_new(inode, tty->link);
686 if (retval) 682 if (retval)
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index cd5b829634ea..949067a0bd47 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -188,6 +188,41 @@ void free_tty_struct(struct tty_struct *tty)
188 kfree(tty); 188 kfree(tty);
189} 189}
190 190
191static inline struct tty_struct *file_tty(struct file *file)
192{
193 return ((struct tty_file_private *)file->private_data)->tty;
194}
195
196/* Associate a new file with the tty structure */
197void tty_add_file(struct tty_struct *tty, struct file *file)
198{
199 struct tty_file_private *priv;
200
201 /* XXX: must implement proper error handling in callers */
202 priv = kmalloc(sizeof(*priv), GFP_KERNEL|__GFP_NOFAIL);
203
204 priv->tty = tty;
205 priv->file = file;
206 file->private_data = priv;
207
208 spin_lock(&tty_files_lock);
209 list_add(&priv->list, &tty->tty_files);
210 spin_unlock(&tty_files_lock);
211}
212
213/* Delete file from its tty */
214void tty_del_file(struct file *file)
215{
216 struct tty_file_private *priv = file->private_data;
217
218 spin_lock(&tty_files_lock);
219 list_del(&priv->list);
220 spin_unlock(&tty_files_lock);
221 file->private_data = NULL;
222 kfree(priv);
223}
224
225
191#define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) 226#define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base)
192 227
193/** 228/**
@@ -500,6 +535,7 @@ void __tty_hangup(struct tty_struct *tty)
500 struct file *cons_filp = NULL; 535 struct file *cons_filp = NULL;
501 struct file *filp, *f = NULL; 536 struct file *filp, *f = NULL;
502 struct task_struct *p; 537 struct task_struct *p;
538 struct tty_file_private *priv;
503 int closecount = 0, n; 539 int closecount = 0, n;
504 unsigned long flags; 540 unsigned long flags;
505 int refs = 0; 541 int refs = 0;
@@ -509,7 +545,7 @@ void __tty_hangup(struct tty_struct *tty)
509 545
510 546
511 spin_lock(&redirect_lock); 547 spin_lock(&redirect_lock);
512 if (redirect && redirect->private_data == tty) { 548 if (redirect && file_tty(redirect) == tty) {
513 f = redirect; 549 f = redirect;
514 redirect = NULL; 550 redirect = NULL;
515 } 551 }
@@ -524,7 +560,8 @@ void __tty_hangup(struct tty_struct *tty)
524 560
525 spin_lock(&tty_files_lock); 561 spin_lock(&tty_files_lock);
526 /* This breaks for file handles being sent over AF_UNIX sockets ? */ 562 /* This breaks for file handles being sent over AF_UNIX sockets ? */
527 list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) { 563 list_for_each_entry(priv, &tty->tty_files, list) {
564 filp = priv->file;
528 if (filp->f_op->write == redirected_tty_write) 565 if (filp->f_op->write == redirected_tty_write)
529 cons_filp = filp; 566 cons_filp = filp;
530 if (filp->f_op->write != tty_write) 567 if (filp->f_op->write != tty_write)
@@ -892,12 +929,10 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
892 loff_t *ppos) 929 loff_t *ppos)
893{ 930{
894 int i; 931 int i;
895 struct tty_struct *tty; 932 struct inode *inode = file->f_path.dentry->d_inode;
896 struct inode *inode; 933 struct tty_struct *tty = file_tty(file);
897 struct tty_ldisc *ld; 934 struct tty_ldisc *ld;
898 935
899 tty = file->private_data;
900 inode = file->f_path.dentry->d_inode;
901 if (tty_paranoia_check(tty, inode, "tty_read")) 936 if (tty_paranoia_check(tty, inode, "tty_read"))
902 return -EIO; 937 return -EIO;
903 if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) 938 if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags)))
@@ -1068,12 +1103,11 @@ void tty_write_message(struct tty_struct *tty, char *msg)
1068static ssize_t tty_write(struct file *file, const char __user *buf, 1103static ssize_t tty_write(struct file *file, const char __user *buf,
1069 size_t count, loff_t *ppos) 1104 size_t count, loff_t *ppos)
1070{ 1105{
1071 struct tty_struct *tty;
1072 struct inode *inode = file->f_path.dentry->d_inode; 1106 struct inode *inode = file->f_path.dentry->d_inode;
1107 struct tty_struct *tty = file_tty(file);
1108 struct tty_ldisc *ld;
1073 ssize_t ret; 1109 ssize_t ret;
1074 struct tty_ldisc *ld;
1075 1110
1076 tty = file->private_data;
1077 if (tty_paranoia_check(tty, inode, "tty_write")) 1111 if (tty_paranoia_check(tty, inode, "tty_write"))
1078 return -EIO; 1112 return -EIO;
1079 if (!tty || !tty->ops->write || 1113 if (!tty || !tty->ops->write ||
@@ -1510,13 +1544,13 @@ static void release_tty(struct tty_struct *tty, int idx)
1510 1544
1511int tty_release(struct inode *inode, struct file *filp) 1545int tty_release(struct inode *inode, struct file *filp)
1512{ 1546{
1513 struct tty_struct *tty, *o_tty; 1547 struct tty_struct *tty = file_tty(filp);
1548 struct tty_struct *o_tty;
1514 int pty_master, tty_closing, o_tty_closing, do_sleep; 1549 int pty_master, tty_closing, o_tty_closing, do_sleep;
1515 int devpts; 1550 int devpts;
1516 int idx; 1551 int idx;
1517 char buf[64]; 1552 char buf[64];
1518 1553
1519 tty = filp->private_data;
1520 if (tty_paranoia_check(tty, inode, "tty_release_dev")) 1554 if (tty_paranoia_check(tty, inode, "tty_release_dev"))
1521 return 0; 1555 return 0;
1522 1556
@@ -1674,11 +1708,7 @@ int tty_release(struct inode *inode, struct file *filp)
1674 * - do_tty_hangup no longer sees this file descriptor as 1708 * - do_tty_hangup no longer sees this file descriptor as
1675 * something that needs to be handled for hangups. 1709 * something that needs to be handled for hangups.
1676 */ 1710 */
1677 spin_lock(&tty_files_lock); 1711 tty_del_file(filp);
1678 BUG_ON(list_empty(&filp->f_u.fu_list));
1679 list_del_init(&filp->f_u.fu_list);
1680 spin_unlock(&tty_files_lock);
1681 filp->private_data = NULL;
1682 1712
1683 /* 1713 /*
1684 * Perform some housekeeping before deciding whether to return. 1714 * Perform some housekeeping before deciding whether to return.
@@ -1845,12 +1875,8 @@ got_driver:
1845 return PTR_ERR(tty); 1875 return PTR_ERR(tty);
1846 } 1876 }
1847 1877
1848 filp->private_data = tty; 1878 tty_add_file(tty, filp);
1849 BUG_ON(list_empty(&filp->f_u.fu_list)); 1879
1850 file_sb_list_del(filp); /* __dentry_open has put it on the sb list */
1851 spin_lock(&tty_files_lock);
1852 list_add(&filp->f_u.fu_list, &tty->tty_files);
1853 spin_unlock(&tty_files_lock);
1854 check_tty_count(tty, "tty_open"); 1880 check_tty_count(tty, "tty_open");
1855 if (tty->driver->type == TTY_DRIVER_TYPE_PTY && 1881 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
1856 tty->driver->subtype == PTY_TYPE_MASTER) 1882 tty->driver->subtype == PTY_TYPE_MASTER)
@@ -1926,11 +1952,10 @@ got_driver:
1926 1952
1927static unsigned int tty_poll(struct file *filp, poll_table *wait) 1953static unsigned int tty_poll(struct file *filp, poll_table *wait)
1928{ 1954{
1929 struct tty_struct *tty; 1955 struct tty_struct *tty = file_tty(filp);
1930 struct tty_ldisc *ld; 1956 struct tty_ldisc *ld;
1931 int ret = 0; 1957 int ret = 0;
1932 1958
1933 tty = filp->private_data;
1934 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) 1959 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll"))
1935 return 0; 1960 return 0;
1936 1961
@@ -1943,11 +1968,10 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait)
1943 1968
1944static int __tty_fasync(int fd, struct file *filp, int on) 1969static int __tty_fasync(int fd, struct file *filp, int on)
1945{ 1970{
1946 struct tty_struct *tty; 1971 struct tty_struct *tty = file_tty(filp);
1947 unsigned long flags; 1972 unsigned long flags;
1948 int retval = 0; 1973 int retval = 0;
1949 1974
1950 tty = filp->private_data;
1951 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) 1975 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
1952 goto out; 1976 goto out;
1953 1977
@@ -2501,13 +2525,13 @@ EXPORT_SYMBOL(tty_pair_get_pty);
2501 */ 2525 */
2502long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 2526long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2503{ 2527{
2504 struct tty_struct *tty, *real_tty; 2528 struct tty_struct *tty = file_tty(file);
2529 struct tty_struct *real_tty;
2505 void __user *p = (void __user *)arg; 2530 void __user *p = (void __user *)arg;
2506 int retval; 2531 int retval;
2507 struct tty_ldisc *ld; 2532 struct tty_ldisc *ld;
2508 struct inode *inode = file->f_dentry->d_inode; 2533 struct inode *inode = file->f_dentry->d_inode;
2509 2534
2510 tty = file->private_data;
2511 if (tty_paranoia_check(tty, inode, "tty_ioctl")) 2535 if (tty_paranoia_check(tty, inode, "tty_ioctl"))
2512 return -EINVAL; 2536 return -EINVAL;
2513 2537
@@ -2629,7 +2653,7 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
2629 unsigned long arg) 2653 unsigned long arg)
2630{ 2654{
2631 struct inode *inode = file->f_dentry->d_inode; 2655 struct inode *inode = file->f_dentry->d_inode;
2632 struct tty_struct *tty = file->private_data; 2656 struct tty_struct *tty = file_tty(file);
2633 struct tty_ldisc *ld; 2657 struct tty_ldisc *ld;
2634 int retval = -ENOIOCTLCMD; 2658 int retval = -ENOIOCTLCMD;
2635 2659
@@ -2721,7 +2745,7 @@ void __do_SAK(struct tty_struct *tty)
2721 if (!filp) 2745 if (!filp)
2722 continue; 2746 continue;
2723 if (filp->f_op->read == tty_read && 2747 if (filp->f_op->read == tty_read &&
2724 filp->private_data == tty) { 2748 file_tty(filp) == tty) {
2725 printk(KERN_NOTICE "SAK: killed process %d" 2749 printk(KERN_NOTICE "SAK: killed process %d"
2726 " (%s): fd#%d opened to the tty\n", 2750 " (%s): fd#%d opened to the tty\n",
2727 task_pid_nr(p), p->comm, i); 2751 task_pid_nr(p), p->comm, i);
diff --git a/fs/internal.h b/fs/internal.h
index 6b706bc60a66..6a5c13a80660 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -80,6 +80,8 @@ extern void chroot_fs_refs(struct path *, struct path *);
80/* 80/*
81 * file_table.c 81 * file_table.c
82 */ 82 */
83extern void file_sb_list_add(struct file *f, struct super_block *sb);
84extern void file_sb_list_del(struct file *f);
83extern void mark_files_ro(struct super_block *); 85extern void mark_files_ro(struct super_block *);
84extern struct file *get_empty_filp(void); 86extern struct file *get_empty_filp(void);
85 87
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 5a9a9e5a3705..5e65add0f163 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2185,8 +2185,6 @@ static inline void insert_inode_hash(struct inode *inode) {
2185 __insert_inode_hash(inode, inode->i_ino); 2185 __insert_inode_hash(inode, inode->i_ino);
2186} 2186}
2187 2187
2188extern void file_sb_list_add(struct file *f, struct super_block *sb);
2189extern void file_sb_list_del(struct file *f);
2190#ifdef CONFIG_BLOCK 2188#ifdef CONFIG_BLOCK
2191extern void submit_bio(int, struct bio *); 2189extern void submit_bio(int, struct bio *);
2192extern int bdev_read_only(struct block_device *); 2190extern int bdev_read_only(struct block_device *);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index f6b371a2514e..67d64e6efe7a 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -329,6 +329,13 @@ struct tty_struct {
329 struct tty_port *port; 329 struct tty_port *port;
330}; 330};
331 331
332/* Each of a tty's open files has private_data pointing to tty_file_private */
333struct tty_file_private {
334 struct tty_struct *tty;
335 struct file *file;
336 struct list_head list;
337};
338
332/* tty magic number */ 339/* tty magic number */
333#define TTY_MAGIC 0x5401 340#define TTY_MAGIC 0x5401
334 341
@@ -458,6 +465,7 @@ extern void proc_clear_tty(struct task_struct *p);
458extern struct tty_struct *get_current_tty(void); 465extern struct tty_struct *get_current_tty(void);
459extern void tty_default_fops(struct file_operations *fops); 466extern void tty_default_fops(struct file_operations *fops);
460extern struct tty_struct *alloc_tty_struct(void); 467extern struct tty_struct *alloc_tty_struct(void);
468extern void tty_add_file(struct tty_struct *tty, struct file *file);
461extern void free_tty_struct(struct tty_struct *tty); 469extern void free_tty_struct(struct tty_struct *tty);
462extern void initialize_tty_struct(struct tty_struct *tty, 470extern void initialize_tty_struct(struct tty_struct *tty,
463 struct tty_driver *driver, int idx); 471 struct tty_driver *driver, int idx);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index bd7da0f0ccf3..4796ddd4e721 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2172,6 +2172,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2172 if (tty) { 2172 if (tty) {
2173 spin_lock(&tty_files_lock); 2173 spin_lock(&tty_files_lock);
2174 if (!list_empty(&tty->tty_files)) { 2174 if (!list_empty(&tty->tty_files)) {
2175 struct tty_file_private *file_priv;
2175 struct inode *inode; 2176 struct inode *inode;
2176 2177
2177 /* Revalidate access to controlling tty. 2178 /* Revalidate access to controlling tty.
@@ -2179,7 +2180,9 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2179 than using file_has_perm, as this particular open 2180 than using file_has_perm, as this particular open
2180 file may belong to another process and we are only 2181 file may belong to another process and we are only
2181 interested in the inode-based check here. */ 2182 interested in the inode-based check here. */
2182 file = list_first_entry(&tty->tty_files, struct file, f_u.fu_list); 2183 file_priv = list_first_entry(&tty->tty_files,
2184 struct tty_file_private, list);
2185 file = file_priv->file;
2183 inode = file->f_path.dentry->d_inode; 2186 inode = file->f_path.dentry->d_inode;
2184 if (inode_has_perm(cred, inode, 2187 if (inode_has_perm(cred, inode,
2185 FILE__READ | FILE__WRITE, NULL)) { 2188 FILE__READ | FILE__WRITE, NULL)) {