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