]>
Commit | Line | Data |
---|---|---|
10679586 | 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,23 +1543,33 @@ | |
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 | #ifdef CONFIG_GRKERNSEC | |
129 | if (!capable(CAP_SYS_TTY_CONFIG)) | |
130 | #else | |
131 | if (!suser()) | |
132 | #endif | |
133 | return -EPERM; | |
134 | + spin_lock(&redirect_lock); | |
135 | + f = redirect; | |
136 | redirect = NULL; | |
137 | + spin_unlock(&redirect_lock); | |
138 | + if (f) | |
139 | + fput(f); | |
140 | return 0; | |
141 | } | |
142 | - if (redirect) | |
143 | + spin_lock(&redirect_lock); | |
144 | + if (redirect) { | |
145 | + spin_unlock(&redirect_lock); | |
146 | return -EBUSY; | |
147 | - redirect = real_tty; | |
148 | + } | |
149 | + get_file(file); | |
150 | + redirect = file; | |
151 | + spin_unlock(&redirect_lock); | |
152 | return 0; | |
153 | } | |
154 | ||
155 | @@ -1759,7 +1786,7 @@ | |
156 | case TIOCSWINSZ: | |
157 | return tiocswinsz(tty, real_tty, (struct winsize *) arg); | |
158 | case TIOCCONS: | |
159 | - return tioccons(inode, tty, real_tty); | |
160 | + return real_tty!=tty ? -EINVAL : tioccons(inode, file); | |
161 | case FIONBIO: | |
162 | return fionbio(file, (int *) arg); | |
163 | case TIOCEXCL: | |
164 | diff -urN S21-rh/include/linux/tty.h S21-rh-tty/include/linux/tty.h | |
165 | --- S21-rh/include/linux/tty.h Sat May 17 11:31:52 2003 | |
166 | +++ S21-rh-tty/include/linux/tty.h Sat May 17 11:32:35 2003 | |
167 | @@ -341,7 +341,6 @@ | |
168 | extern void tty_write_flush(struct tty_struct *); | |
169 | ||
170 | extern struct termios tty_std_termios; | |
171 | -extern struct tty_struct * redirect; | |
172 | extern struct tty_ldisc ldiscs[]; | |
173 | extern int fg_console, last_console, want_console; | |
174 | ||
175 | --- drivers/char/tty_io.c Sat May 17 11:14:02 2003 | |
176 | +++ linux/drivers/char/tty_io.c Sun May 25 07:49:08 2003 | |
177 | @@ -751,6 +751,10 @@ | |
178 | struct tty_struct * tty; | |
179 | struct inode *inode = file->f_dentry->d_inode; | |
180 | ||
181 | + /* Can't seek (pwrite) on ttys. */ | |
182 | + if (ppos != &file->f_pos) | |
183 | + return -ESPIPE; | |
184 | + | |
185 | /* | |
186 | * For now, we redirect writes from /dev/console as | |
187 | * well as /dev/tty0. | |
188 | @@ -770,15 +774,11 @@ | |
189 | spin_unlock(&redirect_lock); | |
190 | ||
191 | if (p) { | |
192 | - ssize_t res = p->f_op->write(p, buf, count, ppos); | |
193 | + ssize_t res = p->f_op->write(p, buf, count, &p->f_pos); | |
194 | fput(p); | |
195 | return res; | |
196 | } | |
197 | } | |
198 | - | |
199 | - /* Can't seek (pwrite) on ttys. */ | |
200 | - if (ppos != &file->f_pos) | |
201 | - return -ESPIPE; | |
202 | ||
203 | tty = (struct tty_struct *)file->private_data; | |
204 | if (tty_paranoia_check(tty, inode->i_rdev, "tty_write")) |