Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
4 : *
5 : * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
6 : * which can be dynamically activated and de-activated by the line
7 : * discipline handling modules (like SLIP).
8 : */
9 :
10 : #include <linux/bits.h>
11 : #include <linux/types.h>
12 : #include <linux/termios.h>
13 : #include <linux/errno.h>
14 : #include <linux/sched/signal.h>
15 : #include <linux/kernel.h>
16 : #include <linux/major.h>
17 : #include <linux/tty.h>
18 : #include <linux/fcntl.h>
19 : #include <linux/string.h>
20 : #include <linux/mm.h>
21 : #include <linux/module.h>
22 : #include <linux/bitops.h>
23 : #include <linux/mutex.h>
24 : #include <linux/compat.h>
25 : #include <linux/termios_internal.h>
26 : #include "tty.h"
27 :
28 : #include <asm/io.h>
29 : #include <linux/uaccess.h>
30 :
31 : #undef DEBUG
32 :
33 : /*
34 : * Internal flag options for termios setting behavior
35 : */
36 : #define TERMIOS_FLUSH BIT(0)
37 : #define TERMIOS_WAIT BIT(1)
38 : #define TERMIOS_TERMIO BIT(2)
39 : #define TERMIOS_OLD BIT(3)
40 :
41 : /**
42 : * tty_chars_in_buffer - characters pending
43 : * @tty: terminal
44 : *
45 : * Returns: the number of bytes of data in the device private output queue. If
46 : * no private method is supplied there is assumed to be no queue on the device.
47 : */
48 92 : unsigned int tty_chars_in_buffer(struct tty_struct *tty)
49 : {
50 92 : if (tty->ops->chars_in_buffer)
51 53 : return tty->ops->chars_in_buffer(tty);
52 39 : return 0;
53 92 : }
54 : EXPORT_SYMBOL(tty_chars_in_buffer);
55 :
56 : /**
57 : * tty_write_room - write queue space
58 : * @tty: terminal
59 : *
60 : * Returns: the number of bytes that can be queued to this device at the present
61 : * time. The result should be treated as a guarantee and the driver cannot
62 : * offer a value it later shrinks by more than the number of bytes written. If
63 : * no method is provided, 2K is always returned and data may be lost as there
64 : * will be no flow control.
65 : */
66 146 : unsigned int tty_write_room(struct tty_struct *tty)
67 : {
68 146 : if (tty->ops->write_room)
69 146 : return tty->ops->write_room(tty);
70 0 : return 2048;
71 146 : }
72 : EXPORT_SYMBOL(tty_write_room);
73 :
74 : /**
75 : * tty_driver_flush_buffer - discard internal buffer
76 : * @tty: terminal
77 : *
78 : * Discard the internal output buffer for this device. If no method is provided,
79 : * then either the buffer cannot be hardware flushed or there is no buffer
80 : * driver side.
81 : */
82 0 : void tty_driver_flush_buffer(struct tty_struct *tty)
83 : {
84 0 : if (tty->ops->flush_buffer)
85 0 : tty->ops->flush_buffer(tty);
86 0 : }
87 : EXPORT_SYMBOL(tty_driver_flush_buffer);
88 :
89 : /**
90 : * tty_unthrottle - flow control
91 : * @tty: terminal
92 : *
93 : * Indicate that a @tty may continue transmitting data down the stack. Takes
94 : * the &tty_struct->termios_rwsem to protect against parallel
95 : * throttle/unthrottle and also to ensure the driver can consistently reference
96 : * its own termios data at this point when implementing software flow control.
97 : *
98 : * Drivers should however remember that the stack can issue a throttle, then
99 : * change flow control method, then unthrottle.
100 : */
101 12 : void tty_unthrottle(struct tty_struct *tty)
102 : {
103 12 : down_write(&tty->termios_rwsem);
104 12 : if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) &&
105 0 : tty->ops->unthrottle)
106 0 : tty->ops->unthrottle(tty);
107 12 : tty->flow_change = TTY_FLOW_NO_CHANGE;
108 12 : up_write(&tty->termios_rwsem);
109 12 : }
110 : EXPORT_SYMBOL(tty_unthrottle);
111 :
112 : /**
113 : * tty_throttle_safe - flow control
114 : * @tty: terminal
115 : *
116 : * Indicate that a @tty should stop transmitting data down the stack.
117 : * tty_throttle_safe() will only attempt throttle if @tty->flow_change is
118 : * %TTY_THROTTLE_SAFE. Prevents an accidental throttle due to race conditions
119 : * when throttling is conditional on factors evaluated prior to throttling.
120 : *
121 : * Returns: %true if @tty is throttled (or was already throttled)
122 : */
123 0 : bool tty_throttle_safe(struct tty_struct *tty)
124 : {
125 0 : guard(mutex)(&tty->throttle_mutex);
126 :
127 0 : if (tty_throttled(tty))
128 0 : return true;
129 :
130 0 : if (tty->flow_change != TTY_THROTTLE_SAFE)
131 0 : return false;
132 :
133 0 : set_bit(TTY_THROTTLED, &tty->flags);
134 0 : if (tty->ops->throttle)
135 0 : tty->ops->throttle(tty);
136 :
137 0 : return true;
138 0 : }
139 :
140 : /**
141 : * tty_unthrottle_safe - flow control
142 : * @tty: terminal
143 : *
144 : * Similar to tty_unthrottle() but will only attempt unthrottle if
145 : * @tty->flow_change is %TTY_UNTHROTTLE_SAFE. Prevents an accidental unthrottle
146 : * due to race conditions when unthrottling is conditional on factors evaluated
147 : * prior to unthrottling.
148 : *
149 : * Returns: %true if @tty is unthrottled (or was already unthrottled)
150 : */
151 0 : bool tty_unthrottle_safe(struct tty_struct *tty)
152 : {
153 0 : guard(mutex)(&tty->throttle_mutex);
154 :
155 0 : if (!tty_throttled(tty))
156 0 : return true;
157 :
158 0 : if (tty->flow_change != TTY_UNTHROTTLE_SAFE)
159 0 : return false;
160 :
161 0 : clear_bit(TTY_THROTTLED, &tty->flags);
162 0 : if (tty->ops->unthrottle)
163 0 : tty->ops->unthrottle(tty);
164 :
165 0 : return true;
166 0 : }
167 :
168 : /**
169 : * tty_wait_until_sent - wait for I/O to finish
170 : * @tty: tty we are waiting for
171 : * @timeout: how long we will wait
172 : *
173 : * Wait for characters pending in a tty driver to hit the wire, or for a
174 : * timeout to occur (eg due to flow control).
175 : *
176 : * Locking: none
177 : */
178 :
179 6 : void tty_wait_until_sent(struct tty_struct *tty, long timeout)
180 : {
181 6 : if (!timeout)
182 0 : timeout = MAX_SCHEDULE_TIMEOUT;
183 :
184 6 : timeout = wait_event_interruptible_timeout(tty->write_wait,
185 : !tty_chars_in_buffer(tty), timeout);
186 6 : if (timeout <= 0)
187 0 : return;
188 :
189 6 : if (timeout == MAX_SCHEDULE_TIMEOUT)
190 0 : timeout = 0;
191 :
192 6 : if (tty->ops->wait_until_sent)
193 0 : tty->ops->wait_until_sent(tty, timeout);
194 6 : }
195 : EXPORT_SYMBOL(tty_wait_until_sent);
196 :
197 :
198 : /*
199 : * Termios Helper Methods
200 : */
201 :
202 0 : static void unset_locked_termios(struct tty_struct *tty, const struct ktermios *old)
203 : {
204 0 : struct ktermios *termios = &tty->termios;
205 0 : struct ktermios *locked = &tty->termios_locked;
206 0 : int i;
207 :
208 : #define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
209 :
210 0 : NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
211 0 : NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
212 0 : NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
213 0 : NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
214 0 : termios->c_line = locked->c_line ? old->c_line : termios->c_line;
215 0 : for (i = 0; i < NCCS; i++)
216 0 : termios->c_cc[i] = locked->c_cc[i] ?
217 0 : old->c_cc[i] : termios->c_cc[i];
218 : /* FIXME: What should we do for i/ospeed */
219 0 : }
220 :
221 : /**
222 : * tty_termios_copy_hw - copy hardware settings
223 : * @new: new termios
224 : * @old: old termios
225 : *
226 : * Propagate the hardware specific terminal setting bits from the @old termios
227 : * structure to the @new one. This is used in cases where the hardware does not
228 : * support reconfiguration or as a helper in some cases where only minimal
229 : * reconfiguration is supported.
230 : */
231 0 : void tty_termios_copy_hw(struct ktermios *new, const struct ktermios *old)
232 : {
233 : /* The bits a dumb device handles in software. Smart devices need
234 : to always provide a set_termios method */
235 0 : new->c_cflag &= HUPCL | CREAD | CLOCAL;
236 0 : new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL);
237 0 : new->c_ispeed = old->c_ispeed;
238 0 : new->c_ospeed = old->c_ospeed;
239 0 : }
240 : EXPORT_SYMBOL(tty_termios_copy_hw);
241 :
242 : /**
243 : * tty_termios_hw_change - check for setting change
244 : * @a: termios
245 : * @b: termios to compare
246 : *
247 : * Check if any of the bits that affect a dumb device have changed between the
248 : * two termios structures, or a speed change is needed.
249 : *
250 : * Returns: %true if change is needed
251 : */
252 0 : bool tty_termios_hw_change(const struct ktermios *a, const struct ktermios *b)
253 : {
254 0 : if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
255 0 : return true;
256 0 : if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL))
257 0 : return true;
258 0 : return false;
259 0 : }
260 : EXPORT_SYMBOL(tty_termios_hw_change);
261 :
262 : /**
263 : * tty_get_char_size - get size of a character
264 : * @cflag: termios cflag value
265 : *
266 : * Returns: size (in bits) of a character depending on @cflag's %CSIZE setting
267 : */
268 0 : unsigned char tty_get_char_size(unsigned int cflag)
269 : {
270 0 : switch (cflag & CSIZE) {
271 : case CS5:
272 0 : return 5;
273 : case CS6:
274 0 : return 6;
275 : case CS7:
276 0 : return 7;
277 0 : case CS8:
278 : default:
279 0 : return 8;
280 : }
281 0 : }
282 : EXPORT_SYMBOL_GPL(tty_get_char_size);
283 :
284 : /**
285 : * tty_get_frame_size - get size of a frame
286 : * @cflag: termios cflag value
287 : *
288 : * Get the size (in bits) of a frame depending on @cflag's %CSIZE, %CSTOPB, and
289 : * %PARENB setting. The result is a sum of character size, start and stop bits
290 : * -- one bit each -- second stop bit (if set), and parity bit (if set).
291 : *
292 : * Returns: size (in bits) of a frame depending on @cflag's setting.
293 : */
294 0 : unsigned char tty_get_frame_size(unsigned int cflag)
295 : {
296 0 : unsigned char bits = 2 + tty_get_char_size(cflag);
297 :
298 0 : if (cflag & CSTOPB)
299 0 : bits++;
300 0 : if (cflag & PARENB)
301 0 : bits++;
302 0 : if (cflag & ADDRB)
303 0 : bits++;
304 :
305 0 : return bits;
306 0 : }
307 : EXPORT_SYMBOL_GPL(tty_get_frame_size);
308 :
309 : /**
310 : * tty_set_termios - update termios values
311 : * @tty: tty to update
312 : * @new_termios: desired new value
313 : *
314 : * Perform updates to the termios values set on this @tty. A master pty's
315 : * termios should never be set.
316 : *
317 : * Locking: &tty_struct->termios_rwsem
318 : */
319 0 : int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
320 : {
321 0 : struct ktermios old_termios;
322 0 : struct tty_ldisc *ld;
323 :
324 0 : WARN_ON(tty->driver->type == TTY_DRIVER_TYPE_PTY &&
325 : tty->driver->subtype == PTY_TYPE_MASTER);
326 : /*
327 : * Perform the actual termios internal changes under lock.
328 : */
329 :
330 :
331 : /* FIXME: we need to decide on some locking/ordering semantics
332 : for the set_termios notification eventually */
333 0 : down_write(&tty->termios_rwsem);
334 0 : old_termios = tty->termios;
335 0 : tty->termios = *new_termios;
336 0 : unset_locked_termios(tty, &old_termios);
337 : /* Reset any ADDRB changes, ADDRB is changed through ->rs485_config() */
338 0 : tty->termios.c_cflag ^= (tty->termios.c_cflag ^ old_termios.c_cflag) & ADDRB;
339 :
340 0 : if (tty->ops->set_termios)
341 0 : tty->ops->set_termios(tty, &old_termios);
342 : else
343 0 : tty_termios_copy_hw(&tty->termios, &old_termios);
344 :
345 0 : ld = tty_ldisc_ref(tty);
346 0 : if (ld != NULL) {
347 0 : if (ld->ops->set_termios)
348 0 : ld->ops->set_termios(tty, &old_termios);
349 0 : tty_ldisc_deref(ld);
350 0 : }
351 0 : up_write(&tty->termios_rwsem);
352 0 : return 0;
353 0 : }
354 : EXPORT_SYMBOL_GPL(tty_set_termios);
355 :
356 :
357 : /*
358 : * Translate a "termio" structure into a "termios". Ugh.
359 : */
360 0 : __weak int user_termio_to_kernel_termios(struct ktermios *termios,
361 : struct termio __user *termio)
362 : {
363 0 : struct termio v;
364 :
365 0 : if (copy_from_user(&v, termio, sizeof(struct termio)))
366 0 : return -EFAULT;
367 :
368 0 : termios->c_iflag = (0xffff0000 & termios->c_iflag) | v.c_iflag;
369 0 : termios->c_oflag = (0xffff0000 & termios->c_oflag) | v.c_oflag;
370 0 : termios->c_cflag = (0xffff0000 & termios->c_cflag) | v.c_cflag;
371 0 : termios->c_lflag = (0xffff0000 & termios->c_lflag) | v.c_lflag;
372 0 : termios->c_line = (0xffff0000 & termios->c_lflag) | v.c_line;
373 0 : memcpy(termios->c_cc, v.c_cc, NCC);
374 0 : return 0;
375 0 : }
376 :
377 : /*
378 : * Translate a "termios" structure into a "termio". Ugh.
379 : */
380 0 : __weak int kernel_termios_to_user_termio(struct termio __user *termio,
381 : struct ktermios *termios)
382 : {
383 0 : struct termio v;
384 0 : memset(&v, 0, sizeof(struct termio));
385 0 : v.c_iflag = termios->c_iflag;
386 0 : v.c_oflag = termios->c_oflag;
387 0 : v.c_cflag = termios->c_cflag;
388 0 : v.c_lflag = termios->c_lflag;
389 0 : v.c_line = termios->c_line;
390 0 : memcpy(v.c_cc, termios->c_cc, NCC);
391 0 : return copy_to_user(termio, &v, sizeof(struct termio));
392 0 : }
393 :
394 : #ifdef TCGETS2
395 0 : __weak int user_termios_to_kernel_termios(struct ktermios *k,
396 : struct termios2 __user *u)
397 : {
398 0 : return copy_from_user(k, u, sizeof(struct termios2));
399 : }
400 0 : __weak int kernel_termios_to_user_termios(struct termios2 __user *u,
401 : struct ktermios *k)
402 : {
403 0 : return copy_to_user(u, k, sizeof(struct termios2));
404 : }
405 0 : __weak int user_termios_to_kernel_termios_1(struct ktermios *k,
406 : struct termios __user *u)
407 : {
408 0 : return copy_from_user(k, u, sizeof(struct termios));
409 : }
410 18 : __weak int kernel_termios_to_user_termios_1(struct termios __user *u,
411 : struct ktermios *k)
412 : {
413 18 : return copy_to_user(u, k, sizeof(struct termios));
414 : }
415 :
416 : #else
417 :
418 : __weak int user_termios_to_kernel_termios(struct ktermios *k,
419 : struct termios __user *u)
420 : {
421 : return copy_from_user(k, u, sizeof(struct termios));
422 : }
423 : __weak int kernel_termios_to_user_termios(struct termios __user *u,
424 : struct ktermios *k)
425 : {
426 : return copy_to_user(u, k, sizeof(struct termios));
427 : }
428 : #endif /* TCGETS2 */
429 :
430 : /**
431 : * set_termios - set termios values for a tty
432 : * @tty: terminal device
433 : * @arg: user data
434 : * @opt: option information
435 : *
436 : * Helper function to prepare termios data and run necessary other functions
437 : * before using tty_set_termios() to do the actual changes.
438 : *
439 : * Locking: called functions take &tty_struct->ldisc_sem and
440 : * &tty_struct->termios_rwsem locks
441 : *
442 : * Returns: 0 on success, an error otherwise
443 : */
444 0 : static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
445 : {
446 0 : struct ktermios tmp_termios;
447 0 : struct tty_ldisc *ld;
448 0 : int retval = tty_check_change(tty);
449 :
450 0 : if (retval)
451 0 : return retval;
452 :
453 0 : down_read(&tty->termios_rwsem);
454 0 : tmp_termios = tty->termios;
455 0 : up_read(&tty->termios_rwsem);
456 :
457 0 : if (opt & TERMIOS_TERMIO) {
458 0 : if (user_termio_to_kernel_termios(&tmp_termios,
459 0 : (struct termio __user *)arg))
460 0 : return -EFAULT;
461 : #ifdef TCGETS2
462 0 : } else if (opt & TERMIOS_OLD) {
463 0 : if (user_termios_to_kernel_termios_1(&tmp_termios,
464 0 : (struct termios __user *)arg))
465 0 : return -EFAULT;
466 0 : } else {
467 0 : if (user_termios_to_kernel_termios(&tmp_termios,
468 0 : (struct termios2 __user *)arg))
469 0 : return -EFAULT;
470 : }
471 : #else
472 : } else if (user_termios_to_kernel_termios(&tmp_termios,
473 : (struct termios __user *)arg))
474 : return -EFAULT;
475 : #endif
476 :
477 : /* If old style Bfoo values are used then load c_ispeed/c_ospeed
478 : * with the real speed so its unconditionally usable */
479 0 : tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
480 0 : tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
481 :
482 0 : if (opt & (TERMIOS_FLUSH|TERMIOS_WAIT)) {
483 : retry_write_wait:
484 0 : retval = wait_event_interruptible(tty->write_wait, !tty_chars_in_buffer(tty));
485 0 : if (retval < 0)
486 0 : return retval;
487 :
488 0 : if (tty_write_lock(tty, false) < 0)
489 0 : goto retry_write_wait;
490 :
491 : /* Racing writer? */
492 0 : if (tty_chars_in_buffer(tty)) {
493 0 : tty_write_unlock(tty);
494 0 : goto retry_write_wait;
495 : }
496 :
497 0 : ld = tty_ldisc_ref(tty);
498 0 : if (ld != NULL) {
499 0 : if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
500 0 : ld->ops->flush_buffer(tty);
501 0 : tty_ldisc_deref(ld);
502 0 : }
503 :
504 0 : if ((opt & TERMIOS_WAIT) && tty->ops->wait_until_sent) {
505 0 : tty->ops->wait_until_sent(tty, 0);
506 0 : if (signal_pending(current)) {
507 0 : tty_write_unlock(tty);
508 0 : return -ERESTARTSYS;
509 : }
510 0 : }
511 :
512 0 : tty_set_termios(tty, &tmp_termios);
513 :
514 0 : tty_write_unlock(tty);
515 0 : } else {
516 0 : tty_set_termios(tty, &tmp_termios);
517 : }
518 :
519 : /* FIXME: Arguably if tmp_termios == tty->termios AND the
520 : actual requested termios was not tmp_termios then we may
521 : want to return an error as no user requested change has
522 : succeeded */
523 0 : return 0;
524 0 : }
525 :
526 18 : static void copy_termios(struct tty_struct *tty, struct ktermios *kterm)
527 : {
528 18 : down_read(&tty->termios_rwsem);
529 18 : *kterm = tty->termios;
530 18 : up_read(&tty->termios_rwsem);
531 18 : }
532 :
533 0 : static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm)
534 : {
535 0 : down_read(&tty->termios_rwsem);
536 0 : *kterm = tty->termios_locked;
537 0 : up_read(&tty->termios_rwsem);
538 0 : }
539 :
540 0 : static int get_termio(struct tty_struct *tty, struct termio __user *termio)
541 : {
542 0 : struct ktermios kterm;
543 0 : copy_termios(tty, &kterm);
544 0 : if (kernel_termios_to_user_termio(termio, &kterm))
545 0 : return -EFAULT;
546 0 : return 0;
547 0 : }
548 :
549 : #ifdef TIOCGETP
550 : /*
551 : * These are deprecated, but there is limited support..
552 : *
553 : * The "sg_flags" translation is a joke..
554 : */
555 : static int get_sgflags(struct tty_struct *tty)
556 : {
557 : int flags = 0;
558 :
559 : if (!L_ICANON(tty)) {
560 : if (L_ISIG(tty))
561 : flags |= 0x02; /* cbreak */
562 : else
563 : flags |= 0x20; /* raw */
564 : }
565 : if (L_ECHO(tty))
566 : flags |= 0x08; /* echo */
567 : if (O_OPOST(tty))
568 : if (O_ONLCR(tty))
569 : flags |= 0x10; /* crmod */
570 : return flags;
571 : }
572 :
573 : static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
574 : {
575 : struct sgttyb tmp;
576 :
577 : down_read(&tty->termios_rwsem);
578 : tmp.sg_ispeed = tty->termios.c_ispeed;
579 : tmp.sg_ospeed = tty->termios.c_ospeed;
580 : tmp.sg_erase = tty->termios.c_cc[VERASE];
581 : tmp.sg_kill = tty->termios.c_cc[VKILL];
582 : tmp.sg_flags = get_sgflags(tty);
583 : up_read(&tty->termios_rwsem);
584 :
585 : return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
586 : }
587 :
588 : static void set_sgflags(struct ktermios *termios, int flags)
589 : {
590 : termios->c_iflag = ICRNL | IXON;
591 : termios->c_oflag = 0;
592 : termios->c_lflag = ISIG | ICANON;
593 : if (flags & 0x02) { /* cbreak */
594 : termios->c_iflag = 0;
595 : termios->c_lflag &= ~ICANON;
596 : }
597 : if (flags & 0x08) { /* echo */
598 : termios->c_lflag |= ECHO | ECHOE | ECHOK |
599 : ECHOCTL | ECHOKE | IEXTEN;
600 : }
601 : if (flags & 0x10) { /* crmod */
602 : termios->c_oflag |= OPOST | ONLCR;
603 : }
604 : if (flags & 0x20) { /* raw */
605 : termios->c_iflag = 0;
606 : termios->c_lflag &= ~(ISIG | ICANON);
607 : }
608 : if (!(termios->c_lflag & ICANON)) {
609 : termios->c_cc[VMIN] = 1;
610 : termios->c_cc[VTIME] = 0;
611 : }
612 : }
613 :
614 : /**
615 : * set_sgttyb - set legacy terminal values
616 : * @tty: tty structure
617 : * @sgttyb: pointer to old style terminal structure
618 : *
619 : * Updates a terminal from the legacy BSD style terminal information structure.
620 : *
621 : * Locking: &tty_struct->termios_rwsem
622 : *
623 : * Returns: 0 on success, an error otherwise
624 : */
625 : static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
626 : {
627 : int retval;
628 : struct sgttyb tmp;
629 : struct ktermios termios;
630 :
631 : retval = tty_check_change(tty);
632 : if (retval)
633 : return retval;
634 :
635 : if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
636 : return -EFAULT;
637 :
638 : down_write(&tty->termios_rwsem);
639 : termios = tty->termios;
640 : termios.c_cc[VERASE] = tmp.sg_erase;
641 : termios.c_cc[VKILL] = tmp.sg_kill;
642 : set_sgflags(&termios, tmp.sg_flags);
643 : /* Try and encode into Bfoo format */
644 : tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
645 : termios.c_ospeed);
646 : up_write(&tty->termios_rwsem);
647 : tty_set_termios(tty, &termios);
648 : return 0;
649 : }
650 : #endif
651 :
652 : #ifdef TIOCGETC
653 : static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
654 : {
655 : struct tchars tmp;
656 :
657 : down_read(&tty->termios_rwsem);
658 : tmp.t_intrc = tty->termios.c_cc[VINTR];
659 : tmp.t_quitc = tty->termios.c_cc[VQUIT];
660 : tmp.t_startc = tty->termios.c_cc[VSTART];
661 : tmp.t_stopc = tty->termios.c_cc[VSTOP];
662 : tmp.t_eofc = tty->termios.c_cc[VEOF];
663 : tmp.t_brkc = tty->termios.c_cc[VEOL2]; /* what is brkc anyway? */
664 : up_read(&tty->termios_rwsem);
665 : return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
666 : }
667 :
668 : static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
669 : {
670 : struct tchars tmp;
671 :
672 : if (copy_from_user(&tmp, tchars, sizeof(tmp)))
673 : return -EFAULT;
674 : down_write(&tty->termios_rwsem);
675 : tty->termios.c_cc[VINTR] = tmp.t_intrc;
676 : tty->termios.c_cc[VQUIT] = tmp.t_quitc;
677 : tty->termios.c_cc[VSTART] = tmp.t_startc;
678 : tty->termios.c_cc[VSTOP] = tmp.t_stopc;
679 : tty->termios.c_cc[VEOF] = tmp.t_eofc;
680 : tty->termios.c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
681 : up_write(&tty->termios_rwsem);
682 : return 0;
683 : }
684 : #endif
685 :
686 : #ifdef TIOCGLTC
687 : static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
688 : {
689 : struct ltchars tmp;
690 :
691 : down_read(&tty->termios_rwsem);
692 : tmp.t_suspc = tty->termios.c_cc[VSUSP];
693 : /* what is dsuspc anyway? */
694 : tmp.t_dsuspc = tty->termios.c_cc[VSUSP];
695 : tmp.t_rprntc = tty->termios.c_cc[VREPRINT];
696 : /* what is flushc anyway? */
697 : tmp.t_flushc = tty->termios.c_cc[VEOL2];
698 : tmp.t_werasc = tty->termios.c_cc[VWERASE];
699 : tmp.t_lnextc = tty->termios.c_cc[VLNEXT];
700 : up_read(&tty->termios_rwsem);
701 : return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
702 : }
703 :
704 : static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
705 : {
706 : struct ltchars tmp;
707 :
708 : if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
709 : return -EFAULT;
710 :
711 : down_write(&tty->termios_rwsem);
712 : tty->termios.c_cc[VSUSP] = tmp.t_suspc;
713 : /* what is dsuspc anyway? */
714 : tty->termios.c_cc[VEOL2] = tmp.t_dsuspc;
715 : tty->termios.c_cc[VREPRINT] = tmp.t_rprntc;
716 : /* what is flushc anyway? */
717 : tty->termios.c_cc[VEOL2] = tmp.t_flushc;
718 : tty->termios.c_cc[VWERASE] = tmp.t_werasc;
719 : tty->termios.c_cc[VLNEXT] = tmp.t_lnextc;
720 : up_write(&tty->termios_rwsem);
721 : return 0;
722 : }
723 : #endif
724 :
725 : /**
726 : * tty_change_softcar - carrier change ioctl helper
727 : * @tty: tty to update
728 : * @enable: enable/disable %CLOCAL
729 : *
730 : * Perform a change to the %CLOCAL state and call into the driver layer to make
731 : * it visible.
732 : *
733 : * Locking: &tty_struct->termios_rwsem.
734 : *
735 : * Returns: 0 on success, an error otherwise
736 : */
737 0 : static int tty_change_softcar(struct tty_struct *tty, bool enable)
738 : {
739 0 : int ret = 0;
740 0 : struct ktermios old;
741 0 : tcflag_t bit = enable ? CLOCAL : 0;
742 :
743 0 : down_write(&tty->termios_rwsem);
744 0 : old = tty->termios;
745 0 : tty->termios.c_cflag &= ~CLOCAL;
746 0 : tty->termios.c_cflag |= bit;
747 0 : if (tty->ops->set_termios)
748 0 : tty->ops->set_termios(tty, &old);
749 0 : if (C_CLOCAL(tty) != bit)
750 0 : ret = -EINVAL;
751 0 : up_write(&tty->termios_rwsem);
752 0 : return ret;
753 0 : }
754 :
755 : /**
756 : * tty_mode_ioctl - mode related ioctls
757 : * @tty: tty for the ioctl
758 : * @cmd: command
759 : * @arg: ioctl argument
760 : *
761 : * Perform non-line discipline specific mode control ioctls. This is designed
762 : * to be called by line disciplines to ensure they provide consistent mode
763 : * setting.
764 : */
765 18 : int tty_mode_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
766 : {
767 18 : struct tty_struct *real_tty;
768 18 : void __user *p = (void __user *)arg;
769 18 : int ret = 0;
770 18 : struct ktermios kterm;
771 :
772 18 : if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
773 18 : tty->driver->subtype == PTY_TYPE_MASTER)
774 0 : real_tty = tty->link;
775 : else
776 18 : real_tty = tty;
777 :
778 18 : switch (cmd) {
779 : #ifdef TIOCGETP
780 : case TIOCGETP:
781 : return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
782 : case TIOCSETP:
783 : case TIOCSETN:
784 : return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
785 : #endif
786 : #ifdef TIOCGETC
787 : case TIOCGETC:
788 : return get_tchars(real_tty, p);
789 : case TIOCSETC:
790 : return set_tchars(real_tty, p);
791 : #endif
792 : #ifdef TIOCGLTC
793 : case TIOCGLTC:
794 : return get_ltchars(real_tty, p);
795 : case TIOCSLTC:
796 : return set_ltchars(real_tty, p);
797 : #endif
798 : case TCSETSF:
799 0 : return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
800 : case TCSETSW:
801 0 : return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
802 : case TCSETS:
803 0 : return set_termios(real_tty, p, TERMIOS_OLD);
804 : #ifndef TCGETS2
805 : case TCGETS:
806 : copy_termios(real_tty, &kterm);
807 : if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
808 : ret = -EFAULT;
809 : return ret;
810 : #else
811 : case TCGETS:
812 18 : copy_termios(real_tty, &kterm);
813 18 : if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
814 0 : ret = -EFAULT;
815 18 : return ret;
816 : case TCGETS2:
817 0 : copy_termios(real_tty, &kterm);
818 0 : if (kernel_termios_to_user_termios((struct termios2 __user *)arg, &kterm))
819 0 : ret = -EFAULT;
820 0 : return ret;
821 : case TCSETSF2:
822 0 : return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT);
823 : case TCSETSW2:
824 0 : return set_termios(real_tty, p, TERMIOS_WAIT);
825 : case TCSETS2:
826 0 : return set_termios(real_tty, p, 0);
827 : #endif
828 : case TCGETA:
829 0 : return get_termio(real_tty, p);
830 : case TCSETAF:
831 0 : return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
832 : case TCSETAW:
833 0 : return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
834 : case TCSETA:
835 0 : return set_termios(real_tty, p, TERMIOS_TERMIO);
836 : #ifndef TCGETS2
837 : case TIOCGLCKTRMIOS:
838 : copy_termios_locked(real_tty, &kterm);
839 : if (kernel_termios_to_user_termios((struct termios __user *)arg, &kterm))
840 : ret = -EFAULT;
841 : return ret;
842 : case TIOCSLCKTRMIOS:
843 : if (!checkpoint_restore_ns_capable(&init_user_ns))
844 : return -EPERM;
845 : copy_termios_locked(real_tty, &kterm);
846 : if (user_termios_to_kernel_termios(&kterm,
847 : (struct termios __user *) arg))
848 : return -EFAULT;
849 : down_write(&real_tty->termios_rwsem);
850 : real_tty->termios_locked = kterm;
851 : up_write(&real_tty->termios_rwsem);
852 : return 0;
853 : #else
854 : case TIOCGLCKTRMIOS:
855 0 : copy_termios_locked(real_tty, &kterm);
856 0 : if (kernel_termios_to_user_termios_1((struct termios __user *)arg, &kterm))
857 0 : ret = -EFAULT;
858 0 : return ret;
859 : case TIOCSLCKTRMIOS:
860 0 : if (!checkpoint_restore_ns_capable(&init_user_ns))
861 0 : return -EPERM;
862 0 : copy_termios_locked(real_tty, &kterm);
863 0 : if (user_termios_to_kernel_termios_1(&kterm,
864 0 : (struct termios __user *) arg))
865 0 : return -EFAULT;
866 0 : down_write(&real_tty->termios_rwsem);
867 0 : real_tty->termios_locked = kterm;
868 0 : up_write(&real_tty->termios_rwsem);
869 0 : return ret;
870 : #endif
871 : #ifdef TCGETX
872 : case TCGETX:
873 : case TCSETX:
874 : case TCSETXW:
875 : case TCSETXF:
876 0 : return -ENOTTY;
877 : #endif
878 : case TIOCGSOFTCAR:
879 0 : copy_termios(real_tty, &kterm);
880 0 : ret = put_user((kterm.c_cflag & CLOCAL) ? 1 : 0,
881 : (int __user *)arg);
882 0 : return ret;
883 : case TIOCSSOFTCAR:
884 0 : if (get_user(arg, (unsigned int __user *) arg))
885 0 : return -EFAULT;
886 0 : return tty_change_softcar(real_tty, arg);
887 : default:
888 0 : return -ENOIOCTLCMD;
889 : }
890 18 : }
891 : EXPORT_SYMBOL_GPL(tty_mode_ioctl);
892 :
893 :
894 : /* Caller guarantees ldisc reference is held */
895 0 : static int __tty_perform_flush(struct tty_struct *tty, unsigned long arg)
896 : {
897 0 : struct tty_ldisc *ld = tty->ldisc;
898 :
899 0 : switch (arg) {
900 : case TCIFLUSH:
901 0 : if (ld && ld->ops->flush_buffer) {
902 0 : ld->ops->flush_buffer(tty);
903 0 : tty_unthrottle(tty);
904 0 : }
905 0 : break;
906 : case TCIOFLUSH:
907 0 : if (ld && ld->ops->flush_buffer) {
908 0 : ld->ops->flush_buffer(tty);
909 0 : tty_unthrottle(tty);
910 0 : }
911 : fallthrough;
912 : case TCOFLUSH:
913 0 : tty_driver_flush_buffer(tty);
914 0 : break;
915 : default:
916 0 : return -EINVAL;
917 : }
918 0 : return 0;
919 0 : }
920 :
921 0 : int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
922 : {
923 0 : struct tty_ldisc *ld;
924 0 : int retval = tty_check_change(tty);
925 0 : if (retval)
926 0 : return retval;
927 :
928 0 : ld = tty_ldisc_ref_wait(tty);
929 0 : retval = __tty_perform_flush(tty, arg);
930 0 : if (ld)
931 0 : tty_ldisc_deref(ld);
932 0 : return retval;
933 0 : }
934 : EXPORT_SYMBOL_GPL(tty_perform_flush);
935 :
936 18 : int n_tty_ioctl_helper(struct tty_struct *tty, unsigned int cmd,
937 : unsigned long arg)
938 : {
939 18 : int retval;
940 :
941 18 : switch (cmd) {
942 : case TCXONC:
943 0 : retval = tty_check_change(tty);
944 0 : if (retval)
945 0 : return retval;
946 0 : switch (arg) {
947 : case TCOOFF:
948 0 : spin_lock_irq(&tty->flow.lock);
949 0 : if (!tty->flow.tco_stopped) {
950 0 : tty->flow.tco_stopped = true;
951 0 : __stop_tty(tty);
952 0 : }
953 0 : spin_unlock_irq(&tty->flow.lock);
954 0 : break;
955 : case TCOON:
956 0 : spin_lock_irq(&tty->flow.lock);
957 0 : if (tty->flow.tco_stopped) {
958 0 : tty->flow.tco_stopped = false;
959 0 : __start_tty(tty);
960 0 : }
961 0 : spin_unlock_irq(&tty->flow.lock);
962 0 : break;
963 : case TCIOFF:
964 0 : if (STOP_CHAR(tty) != __DISABLED_CHAR)
965 0 : retval = tty_send_xchar(tty, STOP_CHAR(tty));
966 0 : break;
967 : case TCION:
968 0 : if (START_CHAR(tty) != __DISABLED_CHAR)
969 0 : retval = tty_send_xchar(tty, START_CHAR(tty));
970 0 : break;
971 : default:
972 0 : return -EINVAL;
973 : }
974 0 : return retval;
975 : case TCFLSH:
976 0 : retval = tty_check_change(tty);
977 0 : if (retval)
978 0 : return retval;
979 0 : return __tty_perform_flush(tty, arg);
980 : default:
981 : /* Try the mode commands */
982 18 : return tty_mode_ioctl(tty, cmd, arg);
983 : }
984 18 : }
985 : EXPORT_SYMBOL(n_tty_ioctl_helper);
|