]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.4.20-tty-fixes-grsec.patch
- obsolete
[packages/kernel.git] / linux-2.4.20-tty-fixes-grsec.patch
CommitLineData
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 :/
3diff -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:
164diff -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"))
This page took 0.194807 seconds and 4 git commands to generate.