]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.4.20-tty-fixes.patch
- ported from linux-2.4.25-atmdd.patch
[packages/kernel.git] / linux-2.4.20-tty-fixes.patch
1  # From RH: TIOCCONS fix and /dev/console write fix
2  # One of them probably fixes CAN-2002-0247, but which??? They didn't tell :/
3 diff -urN S21-rh/drivers/char/tty_io.c S21-rh-tty/drivers/char/tty_io.c
4 --- S21-rh/drivers/char/tty_io.c        Sat May 17 11:31:48 2003
5 +++ S21-rh-tty/drivers/char/tty_io.c    Sat May 17 11:32:35 2003
6 @@ -127,12 +127,6 @@
7  extern struct tty_driver pts_driver[]; /* Unix98 pty slaves;  for /dev/ptmx */
8  #endif
9  
10 -/*
11 - * redirect is the pseudo-tty that console output
12 - * is redirected to if asked by TIOCCONS.
13 - */
14 -struct tty_struct * redirect;
15 -
16  static void initialize_tty_struct(struct tty_struct *tty);
17  
18  static ssize_t tty_read(struct file *, char *, size_t, loff_t *);
19 @@ -430,6 +424,8 @@
20         release:        tty_release,
21  };
22  
23 +static spinlock_t redirect_lock = SPIN_LOCK_UNLOCKED;
24 +static struct file *redirect;
25  /*
26   * This can be called by the "eventd" kernel thread.  That is process synchronous,
27   * but doesn't hold any locks, so we need to make sure we have the appropriate
28 @@ -439,6 +435,7 @@
29  {
30         struct tty_struct *tty = (struct tty_struct *) data;
31         struct file * cons_filp = NULL;
32 +       struct file *f = NULL;
33         struct task_struct *p;
34         struct list_head *l;
35         int    closecount = 0, n;
36 @@ -449,6 +446,15 @@
37  
38         /* inuse_filps is protected by the single kernel lock */
39         lock_kernel();
40 +
41 +       spin_lock(&redirect_lock);
42 +       if (redirect && redirect->private_data == tty) {
43 +               f = redirect;
44 +               redirect = NULL;
45 +       }
46 +       spin_unlock(&redirect_lock);
47 +       if (f)
48 +               fput(f);
49         
50         check_tty_count(tty, "do_tty_hangup");
51         file_list_lock();
52 @@ -748,11 +754,7 @@
53  {
54         int is_console;
55         struct tty_struct * tty;
56 -       struct inode *inode;
57 -
58 -       /* Can't seek (pwrite) on ttys.  */
59 -       if (ppos != &file->f_pos)
60 -               return -ESPIPE;
61 +       struct inode *inode = file->f_dentry->d_inode;
62  
63         /*
64          *      For now, we redirect writes from /dev/console as
65 @@ -762,10 +764,28 @@
66         is_console = (inode->i_rdev == SYSCONS_DEV ||
67                       inode->i_rdev == CONSOLE_DEV);
68  
69 -       if (is_console && redirect)
70 -               tty = redirect;
71 -       else
72 -               tty = (struct tty_struct *)file->private_data;
73 +       if (is_console) {
74 +               struct file *p = NULL;
75 +
76 +               spin_lock(&redirect_lock);
77 +               if (redirect) {
78 +                       get_file(redirect);
79 +                       p = redirect;
80 +               }
81 +               spin_unlock(&redirect_lock);
82 +
83 +               if (p) {
84 +                       ssize_t res = p->f_op->write(p, buf, count, ppos);
85 +                       fput(p);
86 +                       return res;
87 +               }
88 +       }
89 +
90 +       /* Can't seek (pwrite) on ttys.  */
91 +       if (ppos != &file->f_pos)
92 +               return -ESPIPE;
93 +
94 +       tty = (struct tty_struct *)file->private_data;
95         if (tty_paranoia_check(tty, inode->i_rdev, "tty_write"))
96                 return -EIO;
97         if (!tty || !tty->driver.write || (test_bit(TTY_IO_ERROR, &tty->flags)))
98 @@ -1231,7 +1251,7 @@
99         /*
100          * If _either_ side is closing, make sure there aren't any
101          * processes that still think tty or o_tty is their controlling
102 -        * tty.  Also, clear redirect if it points to either tty.
103 +        * tty.
104          */
105         if (tty_closing || o_tty_closing) {
106                 struct task_struct *p;
107 @@ -1245,9 +1265,6 @@
108                         for_each_task_pid(o_tty->session, PIDTYPE_SID, p,l, pid)
109                                 p->tty = NULL;
110                 read_unlock(&tasklist_lock);
111 -
112 -               if (redirect == tty || (o_tty && redirect == o_tty))
113 -                       redirect = NULL;
114         }
115  
116         /* check whether both sides are closing ... */
117 @@ -1526,19 +1543,29 @@
118         return 0;
119  }
120  
121 -static int tioccons(struct inode *inode,
122 -       struct tty_struct *tty, struct tty_struct *real_tty)
123 +static int tioccons(struct inode *inode, struct file *file)
124  {
125         if (inode->i_rdev == SYSCONS_DEV ||
126             inode->i_rdev == CONSOLE_DEV) {
127 +               struct file *f;
128                 if (!suser())
129                         return -EPERM;
130 +               spin_lock(&redirect_lock);
131 +               f = redirect;
132                 redirect = NULL;
133 +               spin_unlock(&redirect_lock);
134 +               if (f)
135 +                       fput(f);
136                 return 0;
137         }
138 -       if (redirect)
139 +       spin_lock(&redirect_lock);
140 +       if (redirect) {
141 +               spin_unlock(&redirect_lock);
142                 return -EBUSY;
143 -       redirect = real_tty;
144 +       }
145 +       get_file(file);
146 +       redirect = file;
147 +       spin_unlock(&redirect_lock);
148         return 0;
149  }
150  
151 @@ -1759,7 +1786,7 @@
152                 case TIOCSWINSZ:
153                         return tiocswinsz(tty, real_tty, (struct winsize *) arg);
154                 case TIOCCONS:
155 -                       return tioccons(inode, tty, real_tty);
156 +                       return real_tty!=tty ? -EINVAL : tioccons(inode, file);
157                 case FIONBIO:
158                         return fionbio(file, (int *) arg);
159                 case TIOCEXCL:
160 diff -urN S21-rh/include/linux/tty.h S21-rh-tty/include/linux/tty.h
161 --- S21-rh/include/linux/tty.h  Sat May 17 11:31:52 2003
162 +++ S21-rh-tty/include/linux/tty.h      Sat May 17 11:32:35 2003
163 @@ -341,7 +341,6 @@
164  extern void tty_write_flush(struct tty_struct *);
165  
166  extern struct termios tty_std_termios;
167 -extern struct tty_struct * redirect;
168  extern struct tty_ldisc ldiscs[];
169  extern int fg_console, last_console, want_console;
170  
171 --- drivers/char/tty_io.c       Sat May 17 11:14:02 2003
172 +++ linux/drivers/char/tty_io.c Sun May 25 07:49:08 2003
173 @@ -751,6 +751,10 @@
174         struct tty_struct * tty;
175         struct inode *inode = file->f_dentry->d_inode;
176  
177 +       /* Can't seek (pwrite) on ttys.  */
178 +       if (ppos != &file->f_pos)
179 +               return -ESPIPE;
180 +
181         /*
182          *      For now, we redirect writes from /dev/console as
183          *      well as /dev/tty0.
184 @@ -770,15 +774,11 @@
185                 spin_unlock(&redirect_lock);
186  
187                 if (p) {
188 -                       ssize_t res = p->f_op->write(p, buf, count, ppos);
189 +                       ssize_t res = p->f_op->write(p, buf, count, &p->f_pos);
190                         fput(p);
191                         return res;
192                 }
193         }
194 -
195 -       /* Can't seek (pwrite) on ttys.  */
196 -       if (ppos != &file->f_pos)
197 -               return -ESPIPE;
198  
199         tty = (struct tty_struct *)file->private_data;
200         if (tty_paranoia_check(tty, inode->i_rdev, "tty_write"))
This page took 0.043968 seconds and 3 git commands to generate.