blob: 88739b1fab459a3c9424063a53d51b28b94bdcce [file] [log] [blame]
Greg Kroah-Hartmane3b3d0f2017-11-06 18:11:51 +01001// SPDX-License-Identifier: GPL-2.0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07003 * Copyright (C) 1991, 1992 Linus Torvalds
4 */
5
6/*
7 * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles
8 * or rs-channels. It also implements echoing, cooked mode etc.
9 *
10 * Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0.
11 *
12 * Modified by Theodore Ts'o, 9/14/92, to dynamically allocate the
13 * tty_struct and tty_queue structures. Previously there was an array
14 * of 256 tty_struct's which was statically allocated, and the
15 * tty_queue structures were allocated at boot time. Both are now
16 * dynamically allocated only when the tty is open.
17 *
18 * Also restructured routines so that there is more of a separation
19 * between the high-level tty routines (tty_io.c and tty_ioctl.c) and
20 * the low-level tty routines (serial.c, pty.c, console.c). This
Alan Cox37bdfb02008-02-08 04:18:47 -080021 * makes for cleaner and more compact code. -TYT, 9/17/92
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 *
23 * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
24 * which can be dynamically activated and de-activated by the line
25 * discipline handling modules (like SLIP).
26 *
27 * NOTE: pay no attention to the line discipline code (yet); its
28 * interface is still subject to change in this version...
29 * -- TYT, 1/31/92
30 *
31 * Added functionality to the OPOST tty handling. No delays, but all
32 * other bits should be there.
33 * -- Nick Holloway <alfie@dcs.warwick.ac.uk>, 27th May 1993.
34 *
35 * Rewrote canonical mode and added more termios flags.
Xiaofei Tan395e7832021-05-12 17:26:14 +080036 * -- julian@uhunix.uhcc.hawaii.edu (J. Cowley), 13Jan94
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 *
38 * Reorganized FASYNC support so mouse code can share it.
39 * -- ctm@ardi.com, 9Sep95
40 *
41 * New TIOCLINUX variants added.
42 * -- mj@k332.feld.cvut.cz, 19-Nov-95
Alan Cox37bdfb02008-02-08 04:18:47 -080043 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070044 * Restrict vt switching via ioctl()
45 * -- grif@cs.ucr.edu, 5-Dec-95
46 *
47 * Move console and virtual terminal code to more appropriate files,
48 * implement CONFIG_VT and generalize console device interface.
49 * -- Marko Kohtala <Marko.Kohtala@hut.fi>, March 97
50 *
Alan Coxd81ed102008-10-13 10:41:42 +010051 * Rewrote tty_init_dev and tty_release_dev to eliminate races.
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 * -- Bill Hawes <whawes@star.net>, June 97
53 *
54 * Added devfs support.
55 * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 13-Jan-1998
56 *
57 * Added support for a Unix98-style ptmx device.
58 * -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
59 *
60 * Reduced memory usage for older ARM systems
61 * -- Russell King <rmk@arm.linux.org.uk>
62 *
63 * Move do_SAK() into process context. Less stack use in devfs functions.
Alan Cox37bdfb02008-02-08 04:18:47 -080064 * alloc_tty_struct() always uses kmalloc()
65 * -- Andrew Morton <andrewm@uow.edu.eu> 17Mar01
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 */
67
Linus Torvalds1da177e2005-04-16 15:20:36 -070068#include <linux/types.h>
69#include <linux/major.h>
70#include <linux/errno.h>
71#include <linux/signal.h>
72#include <linux/fcntl.h>
Ingo Molnar3f07c012017-02-08 18:51:30 +010073#include <linux/sched/signal.h>
Ingo Molnar29930022017-02-08 18:51:36 +010074#include <linux/sched/task.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070075#include <linux/interrupt.h>
76#include <linux/tty.h>
77#include <linux/tty_driver.h>
78#include <linux/tty_flip.h>
79#include <linux/devpts_fs.h>
80#include <linux/file.h>
Al Viro9f3acc32008-04-24 07:44:08 -040081#include <linux/fdtable.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070082#include <linux/console.h>
83#include <linux/timer.h>
84#include <linux/ctype.h>
85#include <linux/kd.h>
86#include <linux/mm.h>
87#include <linux/string.h>
88#include <linux/slab.h>
89#include <linux/poll.h>
Arnd Bergmannb7aff092019-06-06 10:07:36 +020090#include <linux/ppp-ioctl.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070091#include <linux/proc_fs.h>
92#include <linux/init.h>
93#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070094#include <linux/device.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070095#include <linux/wait.h>
96#include <linux/bitops.h>
Domen Puncerb20f3ae2005-06-25 14:58:42 -070097#include <linux/delay.h>
Alan Coxa352def2008-07-16 21:53:12 +010098#include <linux/seq_file.h>
Alan Coxd281da72010-09-16 18:21:24 +010099#include <linux/serial.h>
Manuel Zerpies5a3c6b2512011-06-16 14:07:22 +0200100#include <linux/ratelimit.h>
Al Viroe2112032018-09-11 19:47:09 -0400101#include <linux/compat.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Alan Coxa352def2008-07-16 21:53:12 +0100103#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
105#include <linux/kbd_kern.h>
106#include <linux/vt_kern.h>
107#include <linux/selection.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108
109#include <linux/kmod.h>
Pavel Emelyanovb4888932007-10-18 23:40:14 -0700110#include <linux/nsproxy.h>
Greg Kroah-Hartman98602c02021-04-08 14:51:22 +0200111#include "tty.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112
113#undef TTY_DEBUG_HANGUP
Peter Hurleyaccff792015-07-12 22:49:09 -0400114#ifdef TTY_DEBUG_HANGUP
115# define tty_debug_hangup(tty, f, args...) tty_debug(tty, f, ##args)
116#else
117# define tty_debug_hangup(tty, f, args...) do { } while (0)
118#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119
120#define TTY_PARANOIA_CHECK 1
121#define CHECK_TTY_COUNT 1
122
Alan Coxedc6afc2006-12-08 02:38:44 -0800123struct ktermios tty_std_termios = { /* for the benefit of tty drivers */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 .c_iflag = ICRNL | IXON,
125 .c_oflag = OPOST | ONLCR,
126 .c_cflag = B38400 | CS8 | CREAD | HUPCL,
127 .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
128 ECHOCTL | ECHOKE | IEXTEN,
Alan Coxedc6afc2006-12-08 02:38:44 -0800129 .c_cc = INIT_C_CC,
130 .c_ispeed = 38400,
Peter Hurley133b1302016-01-10 22:41:07 -0800131 .c_ospeed = 38400,
132 /* .c_line = N_TTY, */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133};
134
135EXPORT_SYMBOL(tty_std_termios);
136
137/* This list gets poked at by procfs and various bits of boot up code. This
Xiaofei Tanb426a5b2021-05-12 17:26:18 +0800138 * could do with some rationalisation such as pulling the tty proc function
139 * into this file.
140 */
Alan Cox37bdfb02008-02-08 04:18:47 -0800141
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142LIST_HEAD(tty_drivers); /* linked list of tty drivers */
143
Peter Hurleyd1d027e2016-01-09 21:35:18 -0800144/* Mutex to protect creating and releasing a tty */
Ingo Molnar70522e12006-03-23 03:00:31 -0800145DEFINE_MUTEX(tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -0800147static ssize_t tty_read(struct kiocb *, struct iov_iter *);
Linus Torvalds9bb48c82021-01-19 11:41:16 -0800148static ssize_t tty_write(struct kiocb *, struct iov_iter *);
Al Viroafc9a422017-07-03 06:39:46 -0400149static __poll_t tty_poll(struct file *, poll_table *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150static int tty_open(struct inode *, struct file *);
Paul Fulghume10cc1d2007-05-10 22:22:50 -0700151#ifdef CONFIG_COMPAT
Alan Cox37bdfb02008-02-08 04:18:47 -0800152static long tty_compat_ioctl(struct file *file, unsigned int cmd,
Paul Fulghume10cc1d2007-05-10 22:22:50 -0700153 unsigned long arg);
154#else
155#define tty_compat_ioctl NULL
156#endif
Arnd Bergmannec79d602010-06-01 22:53:01 +0200157static int __tty_fasync(int fd, struct file *filp, int on);
Alan Cox37bdfb02008-02-08 04:18:47 -0800158static int tty_fasync(int fd, struct file *filp, int on);
Christoph Hellwigd5698c22007-02-10 01:46:46 -0800159static void release_tty(struct tty_struct *tty, int idx);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160
Alan Coxaf9b8972006-08-27 01:24:01 -0700161/**
Alan Coxaf9b8972006-08-27 01:24:01 -0700162 * free_tty_struct - free a disused tty
163 * @tty: tty struct to free
164 *
165 * Free the write buffers, tty queue and tty memory itself.
166 *
167 * Locking: none. Must be called after tty is definitely unused
168 */
169
Peter Hurleya3123fd2016-01-09 21:13:48 -0800170static void free_tty_struct(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700171{
Peter Hurleyc8b710b2016-01-09 21:13:46 -0800172 tty_ldisc_deinit(tty);
Markus Elfringa211b1a2014-11-21 13:42:29 +0100173 put_device(tty->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 kfree(tty->write_buf);
Alan Cox89c8d912012-08-08 16:30:13 +0100175 tty->magic = 0xDEADDEAD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 kfree(tty);
177}
178
Nick Piggind996b622010-08-18 04:37:36 +1000179static inline struct tty_struct *file_tty(struct file *file)
180{
181 return ((struct tty_file_private *)file->private_data)->tty;
182}
183
Jiri Slabyfa90e1c2011-10-12 11:32:43 +0200184int tty_alloc_file(struct file *file)
Nick Piggind996b622010-08-18 04:37:36 +1000185{
186 struct tty_file_private *priv;
187
Pekka Enbergf573bd12010-08-24 07:48:34 +0300188 priv = kmalloc(sizeof(*priv), GFP_KERNEL);
189 if (!priv)
190 return -ENOMEM;
Nick Piggind996b622010-08-18 04:37:36 +1000191
Jiri Slabyfa90e1c2011-10-12 11:32:43 +0200192 file->private_data = priv;
193
194 return 0;
195}
196
197/* Associate a new file with the tty structure */
198void tty_add_file(struct tty_struct *tty, struct file *file)
199{
200 struct tty_file_private *priv = file->private_data;
201
Nick Piggind996b622010-08-18 04:37:36 +1000202 priv->tty = tty;
203 priv->file = file;
Nick Piggind996b622010-08-18 04:37:36 +1000204
Peter Hurley4a510962016-01-09 21:35:23 -0800205 spin_lock(&tty->files_lock);
Nick Piggind996b622010-08-18 04:37:36 +1000206 list_add(&priv->list, &tty->tty_files);
Peter Hurley4a510962016-01-09 21:35:23 -0800207 spin_unlock(&tty->files_lock);
Jiri Slabyfa90e1c2011-10-12 11:32:43 +0200208}
Pekka Enbergf573bd12010-08-24 07:48:34 +0300209
Lee Jones08aa5042020-11-04 19:35:25 +0000210/*
Jiri Slabyfa90e1c2011-10-12 11:32:43 +0200211 * tty_free_file - free file->private_data
212 *
213 * This shall be used only for fail path handling when tty_add_file was not
214 * called yet.
215 */
216void tty_free_file(struct file *file)
217{
218 struct tty_file_private *priv = file->private_data;
219
220 file->private_data = NULL;
221 kfree(priv);
Nick Piggind996b622010-08-18 04:37:36 +1000222}
223
224/* Delete file from its tty */
Josh Triplett2520e272012-11-18 21:27:47 -0800225static void tty_del_file(struct file *file)
Nick Piggind996b622010-08-18 04:37:36 +1000226{
227 struct tty_file_private *priv = file->private_data;
Peter Hurley4a510962016-01-09 21:35:23 -0800228 struct tty_struct *tty = priv->tty;
Nick Piggind996b622010-08-18 04:37:36 +1000229
Peter Hurley4a510962016-01-09 21:35:23 -0800230 spin_lock(&tty->files_lock);
Nick Piggind996b622010-08-18 04:37:36 +1000231 list_del(&priv->list);
Peter Hurley4a510962016-01-09 21:35:23 -0800232 spin_unlock(&tty->files_lock);
Jiri Slabyfa90e1c2011-10-12 11:32:43 +0200233 tty_free_file(file);
Nick Piggind996b622010-08-18 04:37:36 +1000234}
235
Alan Coxaf9b8972006-08-27 01:24:01 -0700236/**
237 * tty_name - return tty naming
238 * @tty: tty structure
Alan Coxaf9b8972006-08-27 01:24:01 -0700239 *
240 * Convert a tty structure into a name. The name reflects the kernel
241 * naming policy and if udev is in use may not reflect user space
242 *
243 * Locking: none
244 */
245
Rasmus Villemoes429b4742015-03-31 15:55:59 +0200246const char *tty_name(const struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247{
248 if (!tty) /* Hmm. NULL pointer. That's fun. */
Rasmus Villemoes917162c2015-03-31 15:55:58 +0200249 return "NULL tty";
250 return tty->name;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251}
252
253EXPORT_SYMBOL(tty_name);
254
Peter Hurley0a083ed2015-11-08 13:01:12 -0500255const char *tty_driver_name(const struct tty_struct *tty)
256{
257 if (!tty || !tty->driver)
258 return "";
259 return tty->driver->name;
260}
261
Peter Hurley82b8f882015-11-08 13:01:09 -0500262static int tty_paranoia_check(struct tty_struct *tty, struct inode *inode,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263 const char *routine)
264{
265#ifdef TTY_PARANOIA_CHECK
266 if (!tty) {
Peter Hurley89222e62015-11-08 13:01:18 -0500267 pr_warn("(%d:%d): %s: NULL tty\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 imajor(inode), iminor(inode), routine);
269 return 1;
270 }
271 if (tty->magic != TTY_MAGIC) {
Peter Hurley89222e62015-11-08 13:01:18 -0500272 pr_warn("(%d:%d): %s: bad magic number\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 imajor(inode), iminor(inode), routine);
274 return 1;
275 }
276#endif
277 return 0;
278}
279
Peter Hurleydeb287e2014-11-05 12:12:55 -0500280/* Caller must hold tty_lock */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281static int check_tty_count(struct tty_struct *tty, const char *routine)
282{
283#ifdef CHECK_TTY_COUNT
284 struct list_head *p;
Okash Khawajaa09ac392017-07-20 08:22:36 +0100285 int count = 0, kopen_count = 0;
Alan Cox37bdfb02008-02-08 04:18:47 -0800286
Peter Hurley4a510962016-01-09 21:35:23 -0800287 spin_lock(&tty->files_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 list_for_each(p, &tty->tty_files) {
289 count++;
290 }
Peter Hurley4a510962016-01-09 21:35:23 -0800291 spin_unlock(&tty->files_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
293 tty->driver->subtype == PTY_TYPE_SLAVE &&
294 tty->link && tty->link->count)
295 count++;
Okash Khawajaa09ac392017-07-20 08:22:36 +0100296 if (tty_port_kopened(tty->port))
297 kopen_count++;
298 if (tty->count != (count + kopen_count)) {
299 tty_warn(tty, "%s: tty->count(%d) != (#fd's(%d) + #kopen's(%d))\n",
300 routine, tty->count, count, kopen_count);
301 return (count + kopen_count);
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800302 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303#endif
304 return 0;
305}
306
Alan Coxaf9b8972006-08-27 01:24:01 -0700307/**
Alan Coxaf9b8972006-08-27 01:24:01 -0700308 * get_tty_driver - find device of a tty
Jiri Slabyfa441952020-08-18 10:56:51 +0200309 * @device: device identifier
Alan Coxaf9b8972006-08-27 01:24:01 -0700310 * @index: returns the index of the tty
311 *
312 * This routine returns a tty driver structure, given a device number
313 * and also passes back the index number.
314 *
315 * Locking: caller must hold tty_mutex
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 */
Alan Coxaf9b8972006-08-27 01:24:01 -0700317
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318static struct tty_driver *get_tty_driver(dev_t device, int *index)
319{
320 struct tty_driver *p;
321
322 list_for_each_entry(p, &tty_drivers, tty_drivers) {
323 dev_t base = MKDEV(p->major, p->minor_start);
Xiaofei Tane73b2402021-05-12 17:26:15 +0800324
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325 if (device < base || device >= base + p->num)
326 continue;
327 *index = device - base;
Alan Cox7d7b93c2008-10-13 10:42:09 +0100328 return tty_driver_kref_get(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 }
330 return NULL;
331}
332
Okash Khawajafc61ed52017-06-25 19:40:00 +0100333/**
334 * tty_dev_name_to_number - return dev_t for device name
335 * @name: user space name of device under /dev
336 * @number: pointer to dev_t that this function will populate
337 *
338 * This function converts device names like ttyS0 or ttyUSB1 into dev_t
339 * like (4, 64) or (188, 1). If no corresponding driver is registered then
340 * the function returns -ENODEV.
341 *
342 * Locking: this acquires tty_mutex to protect the tty_drivers list from
343 * being modified while we are traversing it, and makes sure to
344 * release it before exiting.
345 */
346int tty_dev_name_to_number(const char *name, dev_t *number)
347{
348 struct tty_driver *p;
349 int ret;
350 int index, prefix_length = 0;
351 const char *str;
352
353 for (str = name; *str && !isdigit(*str); str++)
354 ;
355
356 if (!*str)
357 return -EINVAL;
358
359 ret = kstrtoint(str, 10, &index);
360 if (ret)
361 return ret;
362
363 prefix_length = str - name;
364 mutex_lock(&tty_mutex);
365
366 list_for_each_entry(p, &tty_drivers, tty_drivers)
367 if (prefix_length == strlen(p->name) && strncmp(name,
368 p->name, prefix_length) == 0) {
369 if (index < p->num) {
370 *number = MKDEV(p->major, p->minor_start + index);
371 goto out;
372 }
373 }
374
375 /* if here then driver wasn't found */
376 ret = -ENODEV;
377out:
378 mutex_unlock(&tty_mutex);
379 return ret;
380}
381EXPORT_SYMBOL_GPL(tty_dev_name_to_number);
382
Jason Wesself2d937f2008-04-17 20:05:37 +0200383#ifdef CONFIG_CONSOLE_POLL
384
385/**
386 * tty_find_polling_driver - find device of a polled tty
387 * @name: name string to match
388 * @line: pointer to resulting tty line nr
389 *
390 * This routine returns a tty driver structure, given a name
391 * and the condition that the tty driver is capable of polled
392 * operation.
393 */
394struct tty_driver *tty_find_polling_driver(char *name, int *line)
395{
396 struct tty_driver *p, *res = NULL;
397 int tty_line = 0;
Jason Wessel0dca0fd2008-09-26 10:36:42 -0500398 int len;
Alan Cox5f0878a2009-06-11 12:46:41 +0100399 char *str, *stp;
Jason Wesself2d937f2008-04-17 20:05:37 +0200400
Jason Wessel0dca0fd2008-09-26 10:36:42 -0500401 for (str = name; *str; str++)
402 if ((*str >= '0' && *str <= '9') || *str == ',')
403 break;
404 if (!*str)
405 return NULL;
406
407 len = str - name;
408 tty_line = simple_strtoul(str, &str, 10);
409
Jason Wesself2d937f2008-04-17 20:05:37 +0200410 mutex_lock(&tty_mutex);
411 /* Search through the tty devices to look for a match */
412 list_for_each_entry(p, &tty_drivers, tty_drivers) {
Miles Chen33a1a7b2018-10-08 10:39:17 +0800413 if (!len || strncmp(name, p->name, len) != 0)
Jason Wessel0dca0fd2008-09-26 10:36:42 -0500414 continue;
Alan Cox5f0878a2009-06-11 12:46:41 +0100415 stp = str;
416 if (*stp == ',')
417 stp++;
418 if (*stp == '\0')
419 stp = NULL;
Jason Wesself2d937f2008-04-17 20:05:37 +0200420
Nathael Pajani6eb68d62010-09-02 16:06:16 +0200421 if (tty_line >= 0 && tty_line < p->num && p->ops &&
Alan Cox5f0878a2009-06-11 12:46:41 +0100422 p->ops->poll_init && !p->ops->poll_init(p, tty_line, stp)) {
Alan Cox7d7b93c2008-10-13 10:42:09 +0100423 res = tty_driver_kref_get(p);
Jason Wesself2d937f2008-04-17 20:05:37 +0200424 *line = tty_line;
425 break;
426 }
427 }
428 mutex_unlock(&tty_mutex);
429
430 return res;
431}
432EXPORT_SYMBOL_GPL(tty_find_polling_driver);
433#endif
434
Linus Torvaldsddc5fda2021-01-21 10:08:15 -0800435static ssize_t hung_up_tty_read(struct kiocb *iocb, struct iov_iter *to)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436{
437 return 0;
438}
439
Linus Torvalds17749852021-01-21 10:04:27 -0800440static ssize_t hung_up_tty_write(struct kiocb *iocb, struct iov_iter *from)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441{
442 return -EIO;
443}
444
445/* No kernel lock held - none needed ;) */
Al Viroafc9a422017-07-03 06:39:46 -0400446static __poll_t hung_up_tty_poll(struct file *filp, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447{
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800448 return EPOLLIN | EPOLLOUT | EPOLLERR | EPOLLHUP | EPOLLRDNORM | EPOLLWRNORM;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449}
450
Alan Cox04f378b2008-04-30 00:53:29 -0700451static long hung_up_tty_ioctl(struct file *file, unsigned int cmd,
452 unsigned long arg)
Paul Fulghum38ad2ed2007-06-16 10:15:55 -0700453{
454 return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
455}
456
Alan Cox37bdfb02008-02-08 04:18:47 -0800457static long hung_up_tty_compat_ioctl(struct file *file,
Paul Fulghum38ad2ed2007-06-16 10:15:55 -0700458 unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459{
460 return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
461}
462
Peter Hurleyf5574742016-01-09 21:45:10 -0800463static int hung_up_tty_fasync(int fd, struct file *file, int on)
464{
465 return -ENOTTY;
466}
467
Masatake YAMATOd01c3282017-07-18 06:27:59 +0900468static void tty_show_fdinfo(struct seq_file *m, struct file *file)
469{
470 struct tty_struct *tty = file_tty(file);
471
472 if (tty && tty->ops && tty->ops->show_fdinfo)
473 tty->ops->show_fdinfo(tty, m);
474}
475
Arjan van de Ven62322d22006-07-03 00:24:21 -0700476static const struct file_operations tty_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 .llseek = no_llseek,
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -0800478 .read_iter = tty_read,
Linus Torvalds9bb48c82021-01-19 11:41:16 -0800479 .write_iter = tty_write,
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -0800480 .splice_read = generic_file_splice_read,
Linus Torvalds9bb48c82021-01-19 11:41:16 -0800481 .splice_write = iter_file_splice_write,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482 .poll = tty_poll,
Alan Cox04f378b2008-04-30 00:53:29 -0700483 .unlocked_ioctl = tty_ioctl,
Paul Fulghume10cc1d2007-05-10 22:22:50 -0700484 .compat_ioctl = tty_compat_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 .open = tty_open,
486 .release = tty_release,
487 .fasync = tty_fasync,
Masatake YAMATOd01c3282017-07-18 06:27:59 +0900488 .show_fdinfo = tty_show_fdinfo,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489};
490
Arjan van de Ven62322d22006-07-03 00:24:21 -0700491static const struct file_operations console_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 .llseek = no_llseek,
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -0800493 .read_iter = tty_read,
Linus Torvalds9bb48c82021-01-19 11:41:16 -0800494 .write_iter = redirected_tty_write,
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -0800495 .splice_read = generic_file_splice_read,
Linus Torvalds9bb48c82021-01-19 11:41:16 -0800496 .splice_write = iter_file_splice_write,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 .poll = tty_poll,
Alan Cox04f378b2008-04-30 00:53:29 -0700498 .unlocked_ioctl = tty_ioctl,
Paul Fulghume10cc1d2007-05-10 22:22:50 -0700499 .compat_ioctl = tty_compat_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 .open = tty_open,
501 .release = tty_release,
502 .fasync = tty_fasync,
503};
504
Arjan van de Ven62322d22006-07-03 00:24:21 -0700505static const struct file_operations hung_up_tty_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506 .llseek = no_llseek,
Linus Torvaldsddc5fda2021-01-21 10:08:15 -0800507 .read_iter = hung_up_tty_read,
Linus Torvalds17749852021-01-21 10:04:27 -0800508 .write_iter = hung_up_tty_write,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 .poll = hung_up_tty_poll,
Alan Cox04f378b2008-04-30 00:53:29 -0700510 .unlocked_ioctl = hung_up_tty_ioctl,
Paul Fulghum38ad2ed2007-06-16 10:15:55 -0700511 .compat_ioctl = hung_up_tty_compat_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 .release = tty_release,
Peter Hurleyf5574742016-01-09 21:45:10 -0800513 .fasync = hung_up_tty_fasync,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514};
515
516static DEFINE_SPINLOCK(redirect_lock);
517static struct file *redirect;
518
519/**
520 * tty_wakeup - request more data
521 * @tty: terminal
522 *
523 * Internal and external helper for wakeups of tty. This function
524 * informs the line discipline if present that the driver is ready
525 * to receive more output data.
526 */
Alan Cox37bdfb02008-02-08 04:18:47 -0800527
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528void tty_wakeup(struct tty_struct *tty)
529{
530 struct tty_ldisc *ld;
Alan Cox37bdfb02008-02-08 04:18:47 -0800531
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) {
533 ld = tty_ldisc_ref(tty);
Alan Cox37bdfb02008-02-08 04:18:47 -0800534 if (ld) {
Alan Coxa352def2008-07-16 21:53:12 +0100535 if (ld->ops->write_wakeup)
536 ld->ops->write_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 tty_ldisc_deref(ld);
538 }
539 }
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800540 wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541}
542
543EXPORT_SYMBOL_GPL(tty_wakeup);
544
545/**
Corey Minyardf4467762020-11-23 18:49:01 -0600546 * tty_release_redirect - Release a redirect on a pty if present
547 * @tty: tty device
548 *
549 * This is available to the pty code so if the master closes, if the
Greg Kroah-Hartmanc776b772021-03-04 17:18:02 +0100550 * slave is a redirect it can release the redirect.
Corey Minyardf4467762020-11-23 18:49:01 -0600551 */
Greg Kroah-Hartmandd9f6112021-04-08 14:51:31 +0200552static struct file *tty_release_redirect(struct tty_struct *tty)
Corey Minyardf4467762020-11-23 18:49:01 -0600553{
554 struct file *f = NULL;
555
556 spin_lock(&redirect_lock);
557 if (redirect && file_tty(redirect) == tty) {
558 f = redirect;
559 redirect = NULL;
560 }
561 spin_unlock(&redirect_lock);
562
563 return f;
564}
Corey Minyardf4467762020-11-23 18:49:01 -0600565
566/**
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200567 * __tty_hangup - actual handler for hangup events
Jiri Slabyfa441952020-08-18 10:56:51 +0200568 * @tty: tty device
Lee Jones08aa5042020-11-04 19:35:25 +0000569 * @exit_session: if non-zero, signal all foreground group processes
Alan Coxaf9b8972006-08-27 01:24:01 -0700570 *
Kevin Cernekeeef4f5272012-12-26 20:43:41 -0800571 * This can be called by a "kworker" kernel thread. That is process
Alan Coxaf9b8972006-08-27 01:24:01 -0700572 * synchronous but doesn't hold any locks, so we need to make sure we
573 * have the appropriate locks for what we're doing.
574 *
575 * The hangup event clears any pending redirections onto the hung up
576 * device. It ensures future writes will error and it does the needed
577 * line discipline hangup and signal delivery. The tty object itself
578 * remains intact.
579 *
580 * Locking:
Arnd Bergmannec79d602010-06-01 22:53:01 +0200581 * BTM
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800582 * redirect lock for undoing redirection
583 * file list lock for manipulating list of ttys
Peter Hurley137084b2013-06-15 07:04:46 -0400584 * tty_ldiscs_lock from called functions
Peter Hurley6a1c0682013-06-15 09:14:23 -0400585 * termios_rwsem resetting termios data
Peter Zijlstra24ec8392006-12-08 02:36:04 -0800586 * tasklist_lock to walk task list for hangup event
587 * ->siglock to protect ->signal/->sighand
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 */
Peter Hurleyf91e2592013-03-06 07:20:56 -0500589static void __tty_hangup(struct tty_struct *tty, int exit_session)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590{
Alan Cox37bdfb02008-02-08 04:18:47 -0800591 struct file *cons_filp = NULL;
Corey Minyardf4467762020-11-23 18:49:01 -0600592 struct file *filp, *f;
Nick Piggind996b622010-08-18 04:37:36 +1000593 struct tty_file_private *priv;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 int closecount = 0, n;
Peter Hurleyea648a42013-03-06 07:20:53 -0500595 int refs;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596
597 if (!tty)
598 return;
599
Corey Minyardf4467762020-11-23 18:49:01 -0600600 f = tty_release_redirect(tty);
Alan Cox37bdfb02008-02-08 04:18:47 -0800601
Alan Cox89c8d912012-08-08 16:30:13 +0100602 tty_lock(tty);
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200603
Peter Hurleycb50e522013-07-31 14:05:45 -0400604 if (test_bit(TTY_HUPPED, &tty->flags)) {
605 tty_unlock(tty);
606 return;
607 }
608
Tejun Heo28b0f8a2018-02-13 07:38:08 -0800609 /*
610 * Some console devices aren't actually hung up for technical and
611 * historical reasons, which can lead to indefinite interruptible
612 * sleep in n_tty_read(). The following explicitly tells
613 * n_tty_read() to abort readers.
614 */
615 set_bit(TTY_HUPPING, &tty->flags);
616
Arnd Bergmannec79d602010-06-01 22:53:01 +0200617 /* inuse_filps is protected by the single tty lock,
Xiaofei Tanb426a5b2021-05-12 17:26:18 +0800618 * this really needs to change if we want to flush the
619 * workqueue with the lock held.
620 */
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200621 check_tty_count(tty, "tty_hangup");
Alan Cox36ba7822009-11-30 13:18:51 +0000622
Peter Hurley4a510962016-01-09 21:35:23 -0800623 spin_lock(&tty->files_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 /* This breaks for file handles being sent over AF_UNIX sockets ? */
Nick Piggind996b622010-08-18 04:37:36 +1000625 list_for_each_entry(priv, &tty->tty_files, list) {
626 filp = priv->file;
Linus Torvalds9bb48c82021-01-19 11:41:16 -0800627 if (filp->f_op->write_iter == redirected_tty_write)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 cons_filp = filp;
Linus Torvalds9bb48c82021-01-19 11:41:16 -0800629 if (filp->f_op->write_iter != tty_write)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 continue;
631 closecount++;
Arnd Bergmannec79d602010-06-01 22:53:01 +0200632 __tty_fasync(-1, filp, 0); /* can't block */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 filp->f_op = &hung_up_tty_fops;
634 }
Peter Hurley4a510962016-01-09 21:35:23 -0800635 spin_unlock(&tty->files_lock);
Alan Cox37bdfb02008-02-08 04:18:47 -0800636
Peter Hurley25fdf242013-03-06 07:20:57 -0500637 refs = tty_signal_session_leader(tty, exit_session);
638 /* Account for the p->signal references we killed */
639 while (refs--)
640 tty_kref_put(tty);
641
Peter Hurley892d1fa2016-01-10 22:41:06 -0800642 tty_ldisc_hangup(tty, cons_filp != NULL);
Alan Cox37bdfb02008-02-08 04:18:47 -0800643
Jiri Slaby64d608d2021-05-05 11:19:06 +0200644 spin_lock_irq(&tty->ctrl.lock);
Alan Coxc65c9bc2009-06-11 12:50:12 +0100645 clear_bit(TTY_THROTTLED, &tty->flags);
Alan Coxc65c9bc2009-06-11 12:50:12 +0100646 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
Jiri Slaby64d608d2021-05-05 11:19:06 +0200647 put_pid(tty->ctrl.session);
648 put_pid(tty->ctrl.pgrp);
649 tty->ctrl.session = NULL;
650 tty->ctrl.pgrp = NULL;
651 tty->ctrl.pktstatus = 0;
652 spin_unlock_irq(&tty->ctrl.lock);
Alan Cox9c9f4de2008-10-13 10:37:26 +0100653
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 /*
Alan Cox37bdfb02008-02-08 04:18:47 -0800655 * If one of the devices matches a console pointer, we
656 * cannot just call hangup() because that will cause
657 * tty->count and state->count to go out of sync.
658 * So we just call close() the right number of times.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659 */
660 if (cons_filp) {
Alan Coxf34d7a52008-04-30 00:54:13 -0700661 if (tty->ops->close)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662 for (n = 0; n < closecount; n++)
Alan Coxf34d7a52008-04-30 00:54:13 -0700663 tty->ops->close(tty, cons_filp);
664 } else if (tty->ops->hangup)
Peter Hurley7c6d3402014-06-16 09:17:08 -0400665 tty->ops->hangup(tty);
Alan Cox37bdfb02008-02-08 04:18:47 -0800666 /*
Peter Hurley892d1fa2016-01-10 22:41:06 -0800667 * We don't want to have driver/ldisc interactions beyond the ones
668 * we did here. The driver layer expects no calls after ->hangup()
669 * from the ldisc side, which is now guaranteed.
Alan Cox37bdfb02008-02-08 04:18:47 -0800670 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 set_bit(TTY_HUPPED, &tty->flags);
Tejun Heo28b0f8a2018-02-13 07:38:08 -0800672 clear_bit(TTY_HUPPING, &tty->flags);
Alan Cox89c8d912012-08-08 16:30:13 +0100673 tty_unlock(tty);
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200674
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 if (f)
676 fput(f);
677}
678
Arnd Bergmannddcd9fb2010-06-01 22:53:08 +0200679static void do_tty_hangup(struct work_struct *work)
680{
681 struct tty_struct *tty =
682 container_of(work, struct tty_struct, hangup_work);
683
Peter Hurleyf91e2592013-03-06 07:20:56 -0500684 __tty_hangup(tty, 0);
Arnd Bergmannddcd9fb2010-06-01 22:53:08 +0200685}
686
Alan Coxaf9b8972006-08-27 01:24:01 -0700687/**
688 * tty_hangup - trigger a hangup event
689 * @tty: tty to hangup
690 *
691 * A carrier loss (virtual or otherwise) has occurred on this like
692 * schedule a hangup sequence to run after this event.
693 */
694
Alan Cox37bdfb02008-02-08 04:18:47 -0800695void tty_hangup(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696{
Peter Hurleyd435cef2015-11-08 13:01:19 -0500697 tty_debug_hangup(tty, "hangup\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 schedule_work(&tty->hangup_work);
699}
700
701EXPORT_SYMBOL(tty_hangup);
702
Alan Coxaf9b8972006-08-27 01:24:01 -0700703/**
704 * tty_vhangup - process vhangup
705 * @tty: tty to hangup
706 *
707 * The user has asked via system call for the terminal to be hung up.
708 * We do this synchronously so that when the syscall returns the process
Robert P. J. Day3a4fa0a2007-10-19 23:10:43 +0200709 * is complete. That guarantee is necessary for security reasons.
Alan Coxaf9b8972006-08-27 01:24:01 -0700710 */
711
Alan Cox37bdfb02008-02-08 04:18:47 -0800712void tty_vhangup(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713{
Peter Hurleyd435cef2015-11-08 13:01:19 -0500714 tty_debug_hangup(tty, "vhangup\n");
Peter Hurleyf91e2592013-03-06 07:20:56 -0500715 __tty_hangup(tty, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716}
Alan Cox37bdfb02008-02-08 04:18:47 -0800717
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718EXPORT_SYMBOL(tty_vhangup);
719
Arnd Bergmann11dbf202010-06-18 14:58:07 +0200720
Alan Coxaf9b8972006-08-27 01:24:01 -0700721/**
Alan Cox2cb59982008-10-13 10:40:30 +0100722 * tty_vhangup_self - process vhangup for own ctty
723 *
724 * Perform a vhangup on the current controlling tty
725 */
726
727void tty_vhangup_self(void)
728{
729 struct tty_struct *tty;
730
Alan Cox2cb59982008-10-13 10:40:30 +0100731 tty = get_current_tty();
732 if (tty) {
733 tty_vhangup(tty);
734 tty_kref_put(tty);
735 }
Alan Cox2cb59982008-10-13 10:40:30 +0100736}
737
738/**
Peter Hurleyf91e2592013-03-06 07:20:56 -0500739 * tty_vhangup_session - hangup session leader exit
740 * @tty: tty to hangup
741 *
742 * The session leader is exiting and hanging up its controlling terminal.
743 * Every process in the foreground process group is signalled SIGHUP.
744 *
745 * We do this synchronously so that when the syscall returns the process
746 * is complete. That guarantee is necessary for security reasons.
747 */
748
Nicolas Pitrea1235b32017-04-12 18:37:16 -0400749void tty_vhangup_session(struct tty_struct *tty)
Peter Hurleyf91e2592013-03-06 07:20:56 -0500750{
Peter Hurleyd435cef2015-11-08 13:01:19 -0500751 tty_debug_hangup(tty, "session hangup\n");
Peter Hurleyf91e2592013-03-06 07:20:56 -0500752 __tty_hangup(tty, 1);
753}
754
755/**
Alan Coxaf9b8972006-08-27 01:24:01 -0700756 * tty_hung_up_p - was tty hung up
757 * @filp: file pointer of tty
758 *
759 * Return true if the tty has been subject to a vhangup or a carrier
760 * loss
761 */
762
Alan Cox37bdfb02008-02-08 04:18:47 -0800763int tty_hung_up_p(struct file *filp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764{
Alan Coxed3f0af2017-01-16 16:54:29 -0600765 return (filp && filp->f_op == &hung_up_tty_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766}
767
768EXPORT_SYMBOL(tty_hung_up_p);
769
Alan Coxaf9b8972006-08-27 01:24:01 -0700770/**
Robert P. J. Daybeb7dd82007-05-09 07:14:03 +0200771 * stop_tty - propagate flow control
Alan Coxaf9b8972006-08-27 01:24:01 -0700772 * @tty: tty to stop
773 *
Peter Hurley01adc802014-09-10 15:06:32 -0400774 * Perform flow control to the driver. May be called
Alan Coxaf9b8972006-08-27 01:24:01 -0700775 * on an already stopped device and will not re-call the driver
776 * method.
777 *
778 * This functionality is used by both the line disciplines for
779 * halting incoming flow and by the driver. It may therefore be
780 * called from any context, may be under the tty atomic_write_lock
781 * but not always.
782 *
783 * Locking:
Jiri Slaby6e94dbc2021-05-05 11:19:05 +0200784 * flow.lock
Alan Coxaf9b8972006-08-27 01:24:01 -0700785 */
786
Peter Hurleyf9e053d2014-09-10 15:06:31 -0400787void __stop_tty(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788{
Jiri Slaby6e94dbc2021-05-05 11:19:05 +0200789 if (tty->flow.stopped)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 return;
Jiri Slaby6e94dbc2021-05-05 11:19:05 +0200791 tty->flow.stopped = true;
Alan Coxf34d7a52008-04-30 00:54:13 -0700792 if (tty->ops->stop)
Peter Hurleyc961bfb2014-11-05 12:26:25 -0500793 tty->ops->stop(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794}
795
Peter Hurleyf9e053d2014-09-10 15:06:31 -0400796void stop_tty(struct tty_struct *tty)
797{
798 unsigned long flags;
799
Jiri Slaby6e94dbc2021-05-05 11:19:05 +0200800 spin_lock_irqsave(&tty->flow.lock, flags);
Peter Hurleyf9e053d2014-09-10 15:06:31 -0400801 __stop_tty(tty);
Jiri Slaby6e94dbc2021-05-05 11:19:05 +0200802 spin_unlock_irqrestore(&tty->flow.lock, flags);
Peter Hurleyf9e053d2014-09-10 15:06:31 -0400803}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804EXPORT_SYMBOL(stop_tty);
805
Alan Coxaf9b8972006-08-27 01:24:01 -0700806/**
Robert P. J. Daybeb7dd82007-05-09 07:14:03 +0200807 * start_tty - propagate flow control
Alan Coxaf9b8972006-08-27 01:24:01 -0700808 * @tty: tty to start
809 *
Peter Hurley01adc802014-09-10 15:06:32 -0400810 * Start a tty that has been stopped if at all possible. If this
811 * tty was previous stopped and is now being started, the driver
812 * start method is invoked and the line discipline woken.
Alan Coxaf9b8972006-08-27 01:24:01 -0700813 *
814 * Locking:
Jiri Slaby6e94dbc2021-05-05 11:19:05 +0200815 * flow.lock
Alan Coxaf9b8972006-08-27 01:24:01 -0700816 */
817
Peter Hurleyf9e053d2014-09-10 15:06:31 -0400818void __start_tty(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819{
Jiri Slaby6e94dbc2021-05-05 11:19:05 +0200820 if (!tty->flow.stopped || tty->flow.tco_stopped)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821 return;
Jiri Slaby6e94dbc2021-05-05 11:19:05 +0200822 tty->flow.stopped = false;
Alan Coxf34d7a52008-04-30 00:54:13 -0700823 if (tty->ops->start)
Peter Hurleyc961bfb2014-11-05 12:26:25 -0500824 tty->ops->start(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 tty_wakeup(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826}
827
Peter Hurleyf9e053d2014-09-10 15:06:31 -0400828void start_tty(struct tty_struct *tty)
829{
830 unsigned long flags;
831
Jiri Slaby6e94dbc2021-05-05 11:19:05 +0200832 spin_lock_irqsave(&tty->flow.lock, flags);
Peter Hurleyf9e053d2014-09-10 15:06:31 -0400833 __start_tty(tty);
Jiri Slaby6e94dbc2021-05-05 11:19:05 +0200834 spin_unlock_irqrestore(&tty->flow.lock, flags);
Peter Hurleyf9e053d2014-09-10 15:06:31 -0400835}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836EXPORT_SYMBOL(start_tty);
837
Arnd Bergmannc884f872018-06-18 16:16:26 +0200838static void tty_update_time(struct timespec64 *time)
Jiri Slaby37b7f3c2013-04-26 13:48:53 +0200839{
Arnd Bergmannc884f872018-06-18 16:16:26 +0200840 time64_t sec = ktime_get_real_seconds();
Greg Kroah-Hartmanfbf47632015-03-26 23:10:27 +0100841
842 /*
843 * We only care if the two values differ in anything other than the
844 * lower three bits (i.e every 8 seconds). If so, then we can update
845 * the time of the tty device, otherwise it could be construded as a
846 * security leak to let userspace know the exact timing of the tty.
847 */
848 if ((sec ^ time->tv_sec) & ~7)
Jiri Slaby37b7f3c2013-04-26 13:48:53 +0200849 time->tv_sec = sec;
850}
851
Linus Torvalds3b830a92021-01-18 13:31:30 -0800852/*
853 * Iterate on the ldisc ->read() function until we've gotten all
854 * the data the ldisc has for us.
855 *
856 * The "cookie" is something that the ldisc read function can fill
857 * in to let us know that there is more data to be had.
858 *
859 * We promise to continue to call the ldisc until it stops returning
860 * data or clears the cookie. The cookie may be something that the
861 * ldisc maintains state for and needs to free.
862 */
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -0800863static int iterate_tty_read(struct tty_ldisc *ld, struct tty_struct *tty,
864 struct file *file, struct iov_iter *to)
Linus Torvalds3b830a92021-01-18 13:31:30 -0800865{
866 int retval = 0;
867 void *cookie = NULL;
868 unsigned long offset = 0;
869 char kernel_buf[64];
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -0800870 size_t count = iov_iter_count(to);
Linus Torvalds3b830a92021-01-18 13:31:30 -0800871
872 do {
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -0800873 int size, copied;
Linus Torvalds3b830a92021-01-18 13:31:30 -0800874
875 size = count > sizeof(kernel_buf) ? sizeof(kernel_buf) : count;
876 size = ld->ops->read(tty, file, kernel_buf, size, &cookie, offset);
877 if (!size)
878 break;
879
Linus Torvalds3b830a92021-01-18 13:31:30 -0800880 if (size < 0) {
Linus Torvaldse71a8d52021-01-21 10:17:25 -0800881 /* Did we have an earlier error (ie -EFAULT)? */
882 if (retval)
883 break;
884 retval = size;
885
886 /*
887 * -EOVERFLOW means we didn't have enough space
888 * for a whole packet, and we shouldn't return
889 * a partial result.
890 */
891 if (retval == -EOVERFLOW)
892 offset = 0;
893 break;
Linus Torvalds3b830a92021-01-18 13:31:30 -0800894 }
895
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -0800896 copied = copy_to_iter(kernel_buf, size, to);
897 offset += copied;
898 count -= copied;
Linus Torvalds3b830a92021-01-18 13:31:30 -0800899
900 /*
901 * If the user copy failed, we still need to do another ->read()
902 * call if we had a cookie to let the ldisc clear up.
903 *
904 * But make sure size is zeroed.
905 */
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -0800906 if (unlikely(copied != size)) {
Linus Torvalds3b830a92021-01-18 13:31:30 -0800907 count = 0;
908 retval = -EFAULT;
909 }
910 } while (cookie);
911
912 /* We always clear tty buffer in case they contained passwords */
913 memzero_explicit(kernel_buf, sizeof(kernel_buf));
914 return offset ? offset : retval;
915}
916
917
Alan Coxaf9b8972006-08-27 01:24:01 -0700918/**
919 * tty_read - read method for tty device files
920 * @file: pointer to tty file
921 * @buf: user buffer
922 * @count: size of user buffer
923 * @ppos: unused
924 *
925 * Perform the read system call function on this terminal device. Checks
926 * for hung up devices before calling the line discipline method.
927 *
928 * Locking:
Alan Cox47f86832008-04-30 00:53:30 -0700929 * Locks the line discipline internally while needed. Multiple
930 * read calls may be outstanding in parallel.
Alan Coxaf9b8972006-08-27 01:24:01 -0700931 */
932
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -0800933static ssize_t tty_read(struct kiocb *iocb, struct iov_iter *to)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934{
935 int i;
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -0800936 struct file *file = iocb->ki_filp;
Jiri Slaby37b7f3c2013-04-26 13:48:53 +0200937 struct inode *inode = file_inode(file);
Nick Piggind996b622010-08-18 04:37:36 +1000938 struct tty_struct *tty = file_tty(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939 struct tty_ldisc *ld;
940
Jiri Slaby37b7f3c2013-04-26 13:48:53 +0200941 if (tty_paranoia_check(tty, inode, "tty_read"))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942 return -EIO;
Peter Hurley18900ca2016-04-09 17:06:48 -0700943 if (!tty || tty_io_error(tty))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944 return -EIO;
945
946 /* We want to wait for the line discipline to sort out in this
Xiaofei Tanb426a5b2021-05-12 17:26:18 +0800947 * situation.
948 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 ld = tty_ldisc_ref_wait(tty);
Peter Hurleye55afd12016-01-10 22:41:01 -0800950 if (!ld)
Linus Torvaldsddc5fda2021-01-21 10:08:15 -0800951 return hung_up_tty_read(iocb, to);
Linus Torvalds3b830a92021-01-18 13:31:30 -0800952 i = -EIO;
Alan Coxa352def2008-07-16 21:53:12 +0100953 if (ld->ops->read)
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -0800954 i = iterate_tty_read(ld, tty, file, to);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 tty_ldisc_deref(ld);
Jiri Slabyb0de59b2013-02-15 15:25:05 +0100956
Arnd Bergmannc884f872018-06-18 16:16:26 +0200957 if (i > 0)
958 tty_update_time(&inode->i_atime);
Jiri Slaby37b7f3c2013-04-26 13:48:53 +0200959
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 return i;
961}
962
Peter Hurley136d5252014-09-10 15:06:34 -0400963static void tty_write_unlock(struct tty_struct *tty)
Alan Cox9c1729d2007-07-15 23:39:43 -0700964{
965 mutex_unlock(&tty->atomic_write_lock);
Linus Torvaldsa9a08842018-02-11 14:34:03 -0800966 wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT);
Alan Cox9c1729d2007-07-15 23:39:43 -0700967}
968
Peter Hurley136d5252014-09-10 15:06:34 -0400969static int tty_write_lock(struct tty_struct *tty, int ndelay)
Alan Cox9c1729d2007-07-15 23:39:43 -0700970{
971 if (!mutex_trylock(&tty->atomic_write_lock)) {
972 if (ndelay)
973 return -EAGAIN;
974 if (mutex_lock_interruptible(&tty->atomic_write_lock))
975 return -ERESTARTSYS;
976 }
977 return 0;
978}
979
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980/*
981 * Split writes up in sane blocksizes to avoid
982 * denial-of-service type attacks
983 */
984static inline ssize_t do_tty_write(
985 ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t),
986 struct tty_struct *tty,
987 struct file *file,
Linus Torvalds9bb48c82021-01-19 11:41:16 -0800988 struct iov_iter *from)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989{
Linus Torvalds9bb48c82021-01-19 11:41:16 -0800990 size_t count = iov_iter_count(from);
Alan Cox9c1729d2007-07-15 23:39:43 -0700991 ssize_t ret, written = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992 unsigned int chunk;
Alan Cox37bdfb02008-02-08 04:18:47 -0800993
Alan Cox9c1729d2007-07-15 23:39:43 -0700994 ret = tty_write_lock(tty, file->f_flags & O_NDELAY);
995 if (ret < 0)
996 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997
998 /*
999 * We chunk up writes into a temporary buffer. This
1000 * simplifies low-level drivers immensely, since they
1001 * don't have locking issues and user mode accesses.
1002 *
1003 * But if TTY_NO_WRITE_SPLIT is set, we should use a
1004 * big chunk-size..
1005 *
1006 * The default chunk-size is 2kB, because the NTTY
1007 * layer has problems with bigger chunks. It will
1008 * claim to be able to handle more characters than
1009 * it actually does.
Alan Coxaf9b8972006-08-27 01:24:01 -07001010 *
1011 * FIXME: This can probably go away now except that 64K chunks
1012 * are too likely to fail unless switched to vmalloc...
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 */
1014 chunk = 2048;
1015 if (test_bit(TTY_NO_WRITE_SPLIT, &tty->flags))
1016 chunk = 65536;
1017 if (count < chunk)
1018 chunk = count;
1019
Ingo Molnar70522e12006-03-23 03:00:31 -08001020 /* write_buf/write_cnt is protected by the atomic_write_lock mutex */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001021 if (tty->write_cnt < chunk) {
Jason Wessel402fda92008-10-13 10:45:36 +01001022 unsigned char *buf_chunk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023
1024 if (chunk < 1024)
1025 chunk = 1024;
1026
Jason Wessel402fda92008-10-13 10:45:36 +01001027 buf_chunk = kmalloc(chunk, GFP_KERNEL);
1028 if (!buf_chunk) {
Alan Cox9c1729d2007-07-15 23:39:43 -07001029 ret = -ENOMEM;
1030 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 }
1032 kfree(tty->write_buf);
1033 tty->write_cnt = chunk;
Jason Wessel402fda92008-10-13 10:45:36 +01001034 tty->write_buf = buf_chunk;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001035 }
1036
1037 /* Do the write .. */
1038 for (;;) {
1039 size_t size = count;
Xiaofei Tane73b2402021-05-12 17:26:15 +08001040
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041 if (size > chunk)
1042 size = chunk;
Linus Torvalds9bb48c82021-01-19 11:41:16 -08001043
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 ret = -EFAULT;
Linus Torvalds9bb48c82021-01-19 11:41:16 -08001045 if (copy_from_iter(tty->write_buf, size, from) != size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046 break;
Linus Torvalds9bb48c82021-01-19 11:41:16 -08001047
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048 ret = write(tty, file, tty->write_buf, size);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 if (ret <= 0)
1050 break;
Linus Torvalds9bb48c82021-01-19 11:41:16 -08001051
Linus Torvalds3342ff22021-02-20 21:15:00 -08001052 written += ret;
1053 if (ret > size)
1054 break;
1055
Linus Torvalds9bb48c82021-01-19 11:41:16 -08001056 /* FIXME! Have Al check this! */
1057 if (ret != size)
1058 iov_iter_revert(from, size-ret);
1059
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 count -= ret;
1061 if (!count)
1062 break;
1063 ret = -ERESTARTSYS;
1064 if (signal_pending(current))
1065 break;
1066 cond_resched();
1067 }
Jiri Slaby37b7f3c2013-04-26 13:48:53 +02001068 if (written) {
Arnd Bergmannc884f872018-06-18 16:16:26 +02001069 tty_update_time(&file_inode(file)->i_mtime);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070 ret = written;
Jiri Slaby37b7f3c2013-04-26 13:48:53 +02001071 }
Alan Cox9c1729d2007-07-15 23:39:43 -07001072out:
1073 tty_write_unlock(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 return ret;
1075}
1076
Alan Cox95f9bfc2008-10-13 10:39:23 +01001077/**
1078 * tty_write_message - write a message to a certain tty, not just the console.
1079 * @tty: the destination tty_struct
1080 * @msg: the message to write
1081 *
1082 * This is used for messages that need to be redirected to a specific tty.
1083 * We don't put it into the syslog queue right now maybe in the future if
1084 * really needed.
1085 *
Arnd Bergmannec79d602010-06-01 22:53:01 +02001086 * We must still hold the BTM and test the CLOSING flag for the moment.
Alan Cox95f9bfc2008-10-13 10:39:23 +01001087 */
1088
1089void tty_write_message(struct tty_struct *tty, char *msg)
1090{
Alan Cox95f9bfc2008-10-13 10:39:23 +01001091 if (tty) {
1092 mutex_lock(&tty->atomic_write_lock);
Alan Cox89c8d912012-08-08 16:30:13 +01001093 tty_lock(tty);
Peter Hurley4b41b952015-10-10 20:28:44 -04001094 if (tty->ops->write && tty->count > 0)
Alan Cox95f9bfc2008-10-13 10:39:23 +01001095 tty->ops->write(tty, msg, strlen(msg));
Peter Hurley4b41b952015-10-10 20:28:44 -04001096 tty_unlock(tty);
Alan Cox95f9bfc2008-10-13 10:39:23 +01001097 tty_write_unlock(tty);
1098 }
Alan Cox95f9bfc2008-10-13 10:39:23 +01001099 return;
1100}
1101
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102
Alan Coxaf9b8972006-08-27 01:24:01 -07001103/**
1104 * tty_write - write method for tty device file
1105 * @file: tty file pointer
1106 * @buf: user data to write
1107 * @count: bytes to write
1108 * @ppos: unused
1109 *
1110 * Write data to a tty device via the line discipline.
1111 *
1112 * Locking:
1113 * Locks the line discipline as required
1114 * Writes to the tty driver are serialized by the atomic_write_lock
1115 * and are then processed in chunks to the device. The line discipline
Joe Petersona88a69c2009-01-02 13:40:53 +00001116 * write method will not be invoked in parallel for each device.
Alan Coxaf9b8972006-08-27 01:24:01 -07001117 */
1118
Linus Torvaldsa9cbbb82021-01-29 12:28:20 -08001119static ssize_t file_tty_write(struct file *file, struct kiocb *iocb, struct iov_iter *from)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120{
Nick Piggind996b622010-08-18 04:37:36 +10001121 struct tty_struct *tty = file_tty(file);
Xiaofei Tan395e7832021-05-12 17:26:14 +08001122 struct tty_ldisc *ld;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 ssize_t ret;
Alan Cox37bdfb02008-02-08 04:18:47 -08001124
Al Viro6131ffa2013-02-27 16:59:05 -05001125 if (tty_paranoia_check(tty, file_inode(file), "tty_write"))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 return -EIO;
Peter Hurley18900ca2016-04-09 17:06:48 -07001127 if (!tty || !tty->ops->write || tty_io_error(tty))
Xiaofei Tan5e4d5ac2021-05-12 17:26:20 +08001128 return -EIO;
Alan Coxf34d7a52008-04-30 00:54:13 -07001129 /* Short term debug to catch buggy drivers */
1130 if (tty->ops->write_room == NULL)
Peter Hurley339f36b2015-11-08 13:01:13 -05001131 tty_err(tty, "missing write_room method\n");
Alan Cox37bdfb02008-02-08 04:18:47 -08001132 ld = tty_ldisc_ref_wait(tty);
Linus Torvalds17749852021-01-21 10:04:27 -08001133 if (!ld)
1134 return hung_up_tty_write(iocb, from);
1135 if (!ld->ops->write)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 ret = -EIO;
1137 else
Linus Torvalds9bb48c82021-01-19 11:41:16 -08001138 ret = do_tty_write(ld->ops->write, tty, file, from);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139 tty_ldisc_deref(ld);
1140 return ret;
1141}
1142
Linus Torvaldsa9cbbb82021-01-29 12:28:20 -08001143static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from)
1144{
1145 return file_tty_write(iocb->ki_filp, iocb, from);
1146}
1147
Linus Torvalds9bb48c82021-01-19 11:41:16 -08001148ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149{
1150 struct file *p = NULL;
1151
1152 spin_lock(&redirect_lock);
Al Virocb0942b2012-08-27 14:48:26 -04001153 if (redirect)
1154 p = get_file(redirect);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155 spin_unlock(&redirect_lock);
1156
Linus Torvaldsa9cbbb82021-01-29 12:28:20 -08001157 /*
Xiaofei Tan44969f82021-05-12 17:26:19 +08001158 * We know the redirected tty is just another tty, we can
Linus Torvaldsa9cbbb82021-01-29 12:28:20 -08001159 * call file_tty_write() directly with that file pointer.
1160 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 if (p) {
1162 ssize_t res;
Xiaofei Tane73b2402021-05-12 17:26:15 +08001163
Linus Torvaldsa9cbbb82021-01-29 12:28:20 -08001164 res = file_tty_write(p, iocb, iter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 fput(p);
1166 return res;
1167 }
Linus Torvalds9bb48c82021-01-19 11:41:16 -08001168 return tty_write(iocb, iter);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169}
1170
Lee Jones08aa5042020-11-04 19:35:25 +00001171/*
Peter Hurley136d5252014-09-10 15:06:34 -04001172 * tty_send_xchar - send priority character
1173 *
1174 * Send a high priority character to the tty even if stopped
1175 *
1176 * Locking: none for xchar method, write ordering for write method.
1177 */
1178
1179int tty_send_xchar(struct tty_struct *tty, char ch)
1180{
Jiri Slaby6e94dbc2021-05-05 11:19:05 +02001181 bool was_stopped = tty->flow.stopped;
Peter Hurley136d5252014-09-10 15:06:34 -04001182
1183 if (tty->ops->send_xchar) {
Peter Hurleyee0c1a62015-11-11 08:03:54 -05001184 down_read(&tty->termios_rwsem);
Peter Hurley136d5252014-09-10 15:06:34 -04001185 tty->ops->send_xchar(tty, ch);
Peter Hurleyee0c1a62015-11-11 08:03:54 -05001186 up_read(&tty->termios_rwsem);
Peter Hurley136d5252014-09-10 15:06:34 -04001187 return 0;
1188 }
1189
1190 if (tty_write_lock(tty, 0) < 0)
1191 return -ERESTARTSYS;
1192
Peter Hurleyee0c1a62015-11-11 08:03:54 -05001193 down_read(&tty->termios_rwsem);
Peter Hurley136d5252014-09-10 15:06:34 -04001194 if (was_stopped)
1195 start_tty(tty);
1196 tty->ops->write(tty, &ch, 1);
1197 if (was_stopped)
1198 stop_tty(tty);
Peter Hurleyee0c1a62015-11-11 08:03:54 -05001199 up_read(&tty->termios_rwsem);
Peter Hurley136d5252014-09-10 15:06:34 -04001200 tty_write_unlock(tty);
1201 return 0;
1202}
1203
Alan Coxaf9b8972006-08-27 01:24:01 -07001204/**
1205 * pty_line_name - generate name for a pty
1206 * @driver: the tty driver in use
1207 * @index: the minor number
1208 * @p: output buffer of at least 6 bytes
1209 *
1210 * Generate a name from a driver reference and write it to the output
1211 * buffer.
1212 *
1213 * Locking: None
1214 */
1215static void pty_line_name(struct tty_driver *driver, int index, char *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216{
Jiri Slabya846dcf2021-03-02 07:22:06 +01001217 static const char ptychar[] = "pqrstuvwxyzabcde";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 int i = index + driver->name_base;
1219 /* ->name is initialized to "ttyp", but "tty" is expected */
1220 sprintf(p, "%s%c%x",
Alan Cox37bdfb02008-02-08 04:18:47 -08001221 driver->subtype == PTY_TYPE_SLAVE ? "tty" : driver->name,
1222 ptychar[i >> 4 & 0xf], i & 0xf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223}
1224
Alan Coxaf9b8972006-08-27 01:24:01 -07001225/**
Alan Cox8b0a88d2008-10-13 10:42:19 +01001226 * tty_line_name - generate name for a tty
Alan Coxaf9b8972006-08-27 01:24:01 -07001227 * @driver: the tty driver in use
1228 * @index: the minor number
1229 * @p: output buffer of at least 7 bytes
1230 *
1231 * Generate a name from a driver reference and write it to the output
Greg Kroah-Hartman5c0a2452014-02-22 14:31:04 -08001232 * buffer.
Alan Coxaf9b8972006-08-27 01:24:01 -07001233 *
1234 * Locking: None
1235 */
Hannes Reinecke723abd82014-02-27 12:30:51 +01001236static ssize_t tty_line_name(struct tty_driver *driver, int index, char *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237{
Jiri Slaby0019b402012-08-08 22:26:43 +02001238 if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE)
Hannes Reinecke723abd82014-02-27 12:30:51 +01001239 return sprintf(p, "%s", driver->name);
Jiri Slaby0019b402012-08-08 22:26:43 +02001240 else
Hannes Reinecke723abd82014-02-27 12:30:51 +01001241 return sprintf(p, "%s%d", driver->name,
1242 index + driver->name_base);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243}
1244
Alan Cox99f1fe12008-10-13 10:42:00 +01001245/**
1246 * tty_driver_lookup_tty() - find an existing tty, if any
1247 * @driver: the driver for the tty
Lee Jones08aa5042020-11-04 19:35:25 +00001248 * @file: file object
Alan Cox99f1fe12008-10-13 10:42:00 +01001249 * @idx: the minor number
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001250 *
Peter Hurleyaa3cb812014-11-05 12:12:51 -05001251 * Return the tty, if found. If not found, return NULL or ERR_PTR() if the
1252 * driver lookup() method returns an error.
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001253 *
Peter Hurleyaa3cb812014-11-05 12:12:51 -05001254 * Locking: tty_mutex must be held. If the tty is found, bump the tty kref.
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001255 */
Jason Wessela47d5452009-01-02 13:43:04 +00001256static struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver,
Linus Torvalds8ead9dd2016-04-25 20:04:08 -07001257 struct file *file, int idx)
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001258{
Peter Hurleyaa3cb812014-11-05 12:12:51 -05001259 struct tty_struct *tty;
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001260
Peter Hurleyaa3cb812014-11-05 12:12:51 -05001261 if (driver->ops->lookup)
Okash Khawaja12e84c72017-05-15 18:45:32 +01001262 if (!file)
1263 tty = ERR_PTR(-EIO);
1264 else
1265 tty = driver->ops->lookup(driver, file, idx);
Peter Hurleyaa3cb812014-11-05 12:12:51 -05001266 else
1267 tty = driver->ttys[idx];
1268
1269 if (!IS_ERR(tty))
1270 tty_kref_get(tty);
1271 return tty;
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001272}
1273
Alan Cox99f1fe12008-10-13 10:42:00 +01001274/**
Alan Coxbf970ee2008-10-13 10:42:39 +01001275 * tty_init_termios - helper for termios setup
1276 * @tty: the tty to set up
1277 *
Johan Hovold8daa89e2019-04-18 18:05:54 +02001278 * Initialise the termios structure for this tty. This runs under
Alan Coxbf970ee2008-10-13 10:42:39 +01001279 * the tty_mutex currently so we can be relaxed about ordering.
1280 */
1281
Peter Hurleya3123fd2016-01-09 21:13:48 -08001282void tty_init_termios(struct tty_struct *tty)
Alan Coxbf970ee2008-10-13 10:42:39 +01001283{
Alan Coxfe6e29f2008-10-13 10:44:08 +01001284 struct ktermios *tp;
Alan Coxbf970ee2008-10-13 10:42:39 +01001285 int idx = tty->index;
1286
Alan Cox36b3c072012-07-17 17:06:57 +01001287 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
1288 tty->termios = tty->driver->init_termios;
1289 else {
1290 /* Check for lazy saved data */
1291 tp = tty->driver->termios[idx];
Peter Hurleyece53402016-01-10 22:40:57 -08001292 if (tp != NULL) {
Alan Cox36b3c072012-07-17 17:06:57 +01001293 tty->termios = *tp;
Peter Hurleyece53402016-01-10 22:40:57 -08001294 tty->termios.c_line = tty->driver->init_termios.c_line;
1295 } else
Alan Cox36b3c072012-07-17 17:06:57 +01001296 tty->termios = tty->driver->init_termios;
Alan Coxbf970ee2008-10-13 10:42:39 +01001297 }
Alan Coxbf970ee2008-10-13 10:42:39 +01001298 /* Compatibility until drivers always set this */
Alan Coxadc8d742012-07-14 15:31:47 +01001299 tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios);
1300 tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios);
Alan Coxbf970ee2008-10-13 10:42:39 +01001301}
Alan Coxfe1ae7f2009-09-19 13:13:33 -07001302EXPORT_SYMBOL_GPL(tty_init_termios);
Alan Coxbf970ee2008-10-13 10:42:39 +01001303
Jiri Slaby66d450e2012-01-30 21:14:28 +01001304int tty_standard_install(struct tty_driver *driver, struct tty_struct *tty)
1305{
Peter Hurleya3123fd2016-01-09 21:13:48 -08001306 tty_init_termios(tty);
Jiri Slaby66d450e2012-01-30 21:14:28 +01001307 tty_driver_kref_get(driver);
1308 tty->count++;
1309 driver->ttys[tty->index] = tty;
1310 return 0;
1311}
1312EXPORT_SYMBOL_GPL(tty_standard_install);
1313
Alan Coxbf970ee2008-10-13 10:42:39 +01001314/**
Alan Cox8b0a88d2008-10-13 10:42:19 +01001315 * tty_driver_install_tty() - install a tty entry in the driver
1316 * @driver: the driver for the tty
1317 * @tty: the tty
1318 *
1319 * Install a tty object into the driver tables. The tty->index field
Alan Coxbf970ee2008-10-13 10:42:39 +01001320 * will be set by the time this is called. This method is responsible
1321 * for ensuring any need additional structures are allocated and
1322 * configured.
Alan Cox8b0a88d2008-10-13 10:42:19 +01001323 *
1324 * Locking: tty_mutex for now
1325 */
1326static int tty_driver_install_tty(struct tty_driver *driver,
1327 struct tty_struct *tty)
1328{
Jiri Slaby66d450e2012-01-30 21:14:28 +01001329 return driver->ops->install ? driver->ops->install(driver, tty) :
1330 tty_standard_install(driver, tty);
Alan Cox8b0a88d2008-10-13 10:42:19 +01001331}
1332
1333/**
1334 * tty_driver_remove_tty() - remove a tty from the driver tables
1335 * @driver: the driver for the tty
Jiri Slabyfa441952020-08-18 10:56:51 +02001336 * @tty: tty to remove
Alan Cox8b0a88d2008-10-13 10:42:19 +01001337 *
1338 * Remvoe a tty object from the driver tables. The tty->index field
1339 * will be set by the time this is called.
1340 *
1341 * Locking: tty_mutex for now
1342 */
Peter Hurley05de87ed2016-01-09 21:13:49 -08001343static void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty)
Alan Cox8b0a88d2008-10-13 10:42:19 +01001344{
1345 if (driver->ops->remove)
1346 driver->ops->remove(driver, tty);
1347 else
1348 driver->ttys[tty->index] = NULL;
1349}
1350
Jiri Slabyfa441952020-08-18 10:56:51 +02001351/**
1352 * tty_reopen() - fast re-open of an open tty
1353 * @tty: the tty to open
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001354 *
Alan Cox99f1fe12008-10-13 10:42:00 +01001355 * Return 0 on success, -errno on error.
Peter Hurley5d93e742014-11-05 12:12:47 -05001356 * Re-opens on master ptys are not allowed and return -EIO.
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001357 *
Peter Hurley5d93e742014-11-05 12:12:47 -05001358 * Locking: Caller must hold tty_lock
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001359 */
Alan Cox99f1fe12008-10-13 10:42:00 +01001360static int tty_reopen(struct tty_struct *tty)
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001361{
1362 struct tty_driver *driver = tty->driver;
Dmitry Safonovd3736d82019-01-09 01:17:40 +00001363 struct tty_ldisc *ld;
1364 int retval = 0;
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001365
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001366 if (driver->type == TTY_DRIVER_TYPE_PTY &&
Peter Hurley5d93e742014-11-05 12:12:47 -05001367 driver->subtype == PTY_TYPE_MASTER)
1368 return -EIO;
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001369
Peter Hurley7f22f6c2016-01-09 21:13:45 -08001370 if (!tty->count)
1371 return -EAGAIN;
1372
Peter Hurley86f2c002014-12-30 10:39:25 -05001373 if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN))
1374 return -EBUSY;
1375
Dmitry Safonovd3736d82019-01-09 01:17:40 +00001376 ld = tty_ldisc_ref_wait(tty);
1377 if (ld) {
1378 tty_ldisc_deref(ld);
1379 } else {
1380 retval = tty_ldisc_lock(tty, 5 * HZ);
1381 if (retval)
1382 return retval;
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001383
Dmitry Safonovd3736d82019-01-09 01:17:40 +00001384 if (!tty->ldisc)
1385 retval = tty_ldisc_reinit(tty, tty->termios.c_line);
1386 tty_ldisc_unlock(tty);
1387 }
Dmitry Safonovcf62a1a2018-11-01 00:24:49 +00001388
1389 if (retval == 0)
1390 tty->count++;
1391
Dmitry Safonovfe324162018-09-18 00:52:52 +01001392 return retval;
Sukadev Bhattiprolu23499702008-10-13 10:41:51 +01001393}
1394
Alan Coxaf9b8972006-08-27 01:24:01 -07001395/**
Alan Coxd81ed102008-10-13 10:41:42 +01001396 * tty_init_dev - initialise a tty device
Alan Coxaf9b8972006-08-27 01:24:01 -07001397 * @driver: tty driver we are opening a device on
1398 * @idx: device index
Alan Coxaf9b8972006-08-27 01:24:01 -07001399 *
1400 * Prepare a tty device. This may not be a "new" clean device but
1401 * could also be an active device. The pty drivers require special
1402 * handling because of this.
1403 *
1404 * Locking:
1405 * The function is called under the tty_mutex, which
1406 * protects us from the tty struct or driver itself going away.
1407 *
1408 * On exit the tty device has the line discipline attached and
1409 * a reference count of 1. If a pair was created for pty/tty use
1410 * and the other was a pty master then it too has a reference count of 1.
1411 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 * WSH 06/09/97: Rewritten to remove races and properly clean up after a
Ingo Molnar70522e12006-03-23 03:00:31 -08001413 * failed open. The new code protects the open with a mutex, so it's
1414 * really quite straightforward. The mutex locking can probably be
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 * relaxed for the (most common) case of reopening a tty.
Jiri Slabyfa441952020-08-18 10:56:51 +02001416 *
1417 * Return: returned tty structure
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 */
Alan Coxaf9b8972006-08-27 01:24:01 -07001419
Konstantin Khlebnikov593a27c2012-01-05 13:04:21 +04001420struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421{
Alan Coxbf970ee2008-10-13 10:42:39 +01001422 struct tty_struct *tty;
Alan Cox73ec06f2008-10-13 10:42:29 +01001423 int retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 /*
1426 * First time open is complex, especially for PTY devices.
1427 * This code guarantees that either everything succeeds and the
1428 * TTY is ready for operation, or else the table slots are vacated
Alan Cox37bdfb02008-02-08 04:18:47 -08001429 * and the allocated memory released. (Except that the termios
Johan Hovold16b00ae2017-03-30 15:39:35 +02001430 * may be retained.)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 */
1432
Alan Cox73ec06f2008-10-13 10:42:29 +01001433 if (!try_module_get(driver->owner))
1434 return ERR_PTR(-ENODEV);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435
Rasmus Villemoes2c964a22014-07-10 21:01:22 +02001436 tty = alloc_tty_struct(driver, idx);
Jiri Slabyd5543502011-03-23 10:48:32 +01001437 if (!tty) {
1438 retval = -ENOMEM;
1439 goto err_module_put;
1440 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441
Alan Cox89c8d912012-08-08 16:30:13 +01001442 tty_lock(tty);
Alan Cox73ec06f2008-10-13 10:42:29 +01001443 retval = tty_driver_install_tty(driver, tty);
Jiri Slabyd5543502011-03-23 10:48:32 +01001444 if (retval < 0)
Peter Hurleyc8b710b2016-01-09 21:13:46 -08001445 goto err_free_tty;
Alan Cox8b0a88d2008-10-13 10:42:19 +01001446
Jiri Slaby04831dc2012-06-04 13:35:36 +02001447 if (!tty->port)
1448 tty->port = driver->ports[idx];
1449
Jiri Slaby2ae0b312019-11-22 11:17:21 +01001450 if (WARN_RATELIMIT(!tty->port,
1451 "%s: %s driver does not set tty->port. This would crash the kernel. Fix the driver!\n",
1452 __func__, tty->driver->name)) {
1453 retval = -EINVAL;
1454 goto err_release_lock;
1455 }
Jiri Slaby5d4121c2012-08-17 14:27:52 +02001456
Gaurav Kohlib027e222018-01-23 13:16:34 +05301457 retval = tty_ldisc_lock(tty, 5 * HZ);
1458 if (retval)
1459 goto err_release_lock;
Jiri Slaby967fab62012-10-18 22:26:46 +02001460 tty->port->itty = tty;
1461
Alan Cox37bdfb02008-02-08 04:18:47 -08001462 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 * Structures all installed ... call the ldisc open routines.
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001464 * If we fail here just call release_tty to clean up. No need
1465 * to decrement the use counts, as release_tty doesn't care.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 */
Alan Coxbf970ee2008-10-13 10:42:39 +01001467 retval = tty_ldisc_setup(tty, tty->link);
Alan Cox01e1abb2008-07-22 11:16:55 +01001468 if (retval)
Jiri Slabyd5543502011-03-23 10:48:32 +01001469 goto err_release_tty;
Gaurav Kohlib027e222018-01-23 13:16:34 +05301470 tty_ldisc_unlock(tty);
Alan Cox89c8d912012-08-08 16:30:13 +01001471 /* Return the tty locked so that it cannot vanish under the caller */
Alan Cox73ec06f2008-10-13 10:42:29 +01001472 return tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473
Peter Hurleyc8b710b2016-01-09 21:13:46 -08001474err_free_tty:
Alan Cox89c8d912012-08-08 16:30:13 +01001475 tty_unlock(tty);
Jiri Slabyd5543502011-03-23 10:48:32 +01001476 free_tty_struct(tty);
1477err_module_put:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478 module_put(driver->owner);
Jiri Slabyd5543502011-03-23 10:48:32 +01001479 return ERR_PTR(retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001481 /* call the tty release_tty routine to clean out this slot */
Jiri Slabyd5543502011-03-23 10:48:32 +01001482err_release_tty:
Gaurav Kohlib027e222018-01-23 13:16:34 +05301483 tty_ldisc_unlock(tty);
Peter Hurley339f36b2015-11-08 13:01:13 -05001484 tty_info_ratelimited(tty, "ldisc open failed (%d), clearing slot %d\n",
1485 retval, idx);
Gaurav Kohlib027e222018-01-23 13:16:34 +05301486err_release_lock:
1487 tty_unlock(tty);
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001488 release_tty(tty, idx);
Alan Cox73ec06f2008-10-13 10:42:29 +01001489 return ERR_PTR(retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490}
1491
Johan Hovoldf51ccf42018-12-04 17:00:36 +01001492/**
1493 * tty_save_termios() - save tty termios data in driver table
1494 * @tty: tty whose termios data to save
1495 *
1496 * Locking: Caller guarantees serialisation with tty_init_termios().
1497 */
1498void tty_save_termios(struct tty_struct *tty)
Alan Coxfeebed62008-10-13 10:41:30 +01001499{
1500 struct ktermios *tp;
1501 int idx = tty->index;
Alan Cox36b3c072012-07-17 17:06:57 +01001502
1503 /* If the port is going to reset then it has no termios to save */
1504 if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
1505 return;
1506
1507 /* Stash the termios data */
1508 tp = tty->driver->termios[idx];
1509 if (tp == NULL) {
Gustavo A. R. Silvaa3241892020-07-23 17:34:22 -05001510 tp = kmalloc(sizeof(*tp), GFP_KERNEL);
Peter Hurley25080652015-11-08 13:01:11 -05001511 if (tp == NULL)
Alan Cox36b3c072012-07-17 17:06:57 +01001512 return;
Dan Carpenter4ac5d702012-07-24 12:51:52 +01001513 tty->driver->termios[idx] = tp;
Alan Coxfeebed62008-10-13 10:41:30 +01001514 }
Alan Cox36b3c072012-07-17 17:06:57 +01001515 *tp = tty->termios;
Alan Coxfeebed62008-10-13 10:41:30 +01001516}
Johan Hovoldf51ccf42018-12-04 17:00:36 +01001517EXPORT_SYMBOL_GPL(tty_save_termios);
Alan Coxfeebed62008-10-13 10:41:30 +01001518
Peter Hurleya2965b72013-03-11 16:44:35 -04001519/**
Peter Hurley949aa642014-11-05 12:12:57 -05001520 * tty_flush_works - flush all works of a tty/pty pair
1521 * @tty: tty device to flush works for (or either end of a pty pair)
Peter Hurleya2965b72013-03-11 16:44:35 -04001522 *
Peter Hurley949aa642014-11-05 12:12:57 -05001523 * Sync flush all works belonging to @tty (and the 'other' tty).
Peter Hurleya2965b72013-03-11 16:44:35 -04001524 */
1525static void tty_flush_works(struct tty_struct *tty)
1526{
1527 flush_work(&tty->SAK_work);
1528 flush_work(&tty->hangup_work);
Peter Hurley949aa642014-11-05 12:12:57 -05001529 if (tty->link) {
1530 flush_work(&tty->link->SAK_work);
1531 flush_work(&tty->link->hangup_work);
1532 }
Peter Hurleya2965b72013-03-11 16:44:35 -04001533}
Alan Coxfeebed62008-10-13 10:41:30 +01001534
Alan Coxaf9b8972006-08-27 01:24:01 -07001535/**
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001536 * release_one_tty - release tty structure memory
Jiri Slabyfa441952020-08-18 10:56:51 +02001537 * @work: work of tty we are obliterating
Alan Coxaf9b8972006-08-27 01:24:01 -07001538 *
1539 * Releases memory associated with a tty structure, and clears out the
1540 * driver table slots. This function is called when a device is no longer
1541 * in use. It also gets called when setup of a device fails.
1542 *
1543 * Locking:
Alan Coxaf9b8972006-08-27 01:24:01 -07001544 * takes the file list lock internally when working on the list
1545 * of ttys that the driver keeps.
Alan Coxb50989d2009-09-19 13:13:22 -07001546 *
1547 * This method gets called from a work queue so that the driver private
Dave Youngf278a2f2009-09-27 16:00:42 +00001548 * cleanup ops can sleep (needed for USB at least)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 */
Alan Coxb50989d2009-09-19 13:13:22 -07001550static void release_one_tty(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551{
Alan Coxb50989d2009-09-19 13:13:22 -07001552 struct tty_struct *tty =
1553 container_of(work, struct tty_struct, hangup_work);
Alan Cox6f967f72008-10-13 10:37:36 +01001554 struct tty_driver *driver = tty->driver;
Cyrill Gorcunovb216df52014-08-08 00:26:15 +04001555 struct module *owner = driver->owner;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556
Dave Youngf278a2f2009-09-27 16:00:42 +00001557 if (tty->ops->cleanup)
1558 tty->ops->cleanup(tty);
1559
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560 tty->magic = 0;
Alan Cox7d7b93c2008-10-13 10:42:09 +01001561 tty_driver_kref_put(driver);
Cyrill Gorcunovb216df52014-08-08 00:26:15 +04001562 module_put(owner);
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001563
Peter Hurley4a510962016-01-09 21:35:23 -08001564 spin_lock(&tty->files_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565 list_del_init(&tty->tty_files);
Peter Hurley4a510962016-01-09 21:35:23 -08001566 spin_unlock(&tty->files_lock);
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001567
Jiri Slaby64d608d2021-05-05 11:19:06 +02001568 put_pid(tty->ctrl.pgrp);
1569 put_pid(tty->ctrl.session);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570 free_tty_struct(tty);
1571}
1572
Alan Coxb50989d2009-09-19 13:13:22 -07001573static void queue_release_one_tty(struct kref *kref)
1574{
1575 struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
Dave Youngf278a2f2009-09-27 16:00:42 +00001576
Alan Coxb50989d2009-09-19 13:13:22 -07001577 /* The hangup queue is now free so we can reuse it rather than
Xiaofei Tanb426a5b2021-05-12 17:26:18 +08001578 * waste a chunk of memory for each port.
1579 */
Alan Coxb50989d2009-09-19 13:13:22 -07001580 INIT_WORK(&tty->hangup_work, release_one_tty);
1581 schedule_work(&tty->hangup_work);
1582}
1583
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001584/**
Alan Cox9c9f4de2008-10-13 10:37:26 +01001585 * tty_kref_put - release a tty kref
1586 * @tty: tty device
1587 *
1588 * Release a reference to a tty device and if need be let the kref
1589 * layer destruct the object for us
1590 */
1591
1592void tty_kref_put(struct tty_struct *tty)
1593{
1594 if (tty)
Alan Coxb50989d2009-09-19 13:13:22 -07001595 kref_put(&tty->kref, queue_release_one_tty);
Alan Cox9c9f4de2008-10-13 10:37:26 +01001596}
1597EXPORT_SYMBOL(tty_kref_put);
1598
1599/**
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001600 * release_tty - release tty structure memory
Lee Jones08aa5042020-11-04 19:35:25 +00001601 * @tty: tty device release
1602 * @idx: index of the tty device release
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001603 *
1604 * Release both @tty and a possible linked partner (think pty pair),
1605 * and decrement the refcount of the backing module.
1606 *
1607 * Locking:
Alan Coxd1552552012-07-27 18:02:54 +01001608 * tty_mutex
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001609 * takes the file list lock internally when working on the list
1610 * of ttys that the driver keeps.
Alan Cox9c9f4de2008-10-13 10:37:26 +01001611 *
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001612 */
1613static void release_tty(struct tty_struct *tty, int idx)
1614{
Alan Cox9c9f4de2008-10-13 10:37:26 +01001615 /* This should always be true but check for the moment */
1616 WARN_ON(tty->index != idx);
Alan Coxd1552552012-07-27 18:02:54 +01001617 WARN_ON(!mutex_is_locked(&tty_mutex));
Alan Cox36b3c072012-07-17 17:06:57 +01001618 if (tty->ops->shutdown)
1619 tty->ops->shutdown(tty);
Johan Hovoldf51ccf42018-12-04 17:00:36 +01001620 tty_save_termios(tty);
Alan Cox36b3c072012-07-17 17:06:57 +01001621 tty_driver_remove_tty(tty->driver, tty);
Matthias Reichl4466d6d2020-11-05 13:34:32 +01001622 if (tty->port)
1623 tty->port->itty = NULL;
Peter Hurley64e377d2013-06-15 09:01:00 -04001624 if (tty->link)
1625 tty->link->port->itty = NULL;
Matthias Reichl4466d6d2020-11-05 13:34:32 +01001626 if (tty->port)
1627 tty_buffer_cancel_work(tty->port);
Sahara2b022ab2017-12-13 09:10:48 +04001628 if (tty->link)
1629 tty_buffer_cancel_work(tty->link->port);
Alan Cox36b3c072012-07-17 17:06:57 +01001630
Markus Elfringa211b1a2014-11-21 13:42:29 +01001631 tty_kref_put(tty->link);
Alan Cox9c9f4de2008-10-13 10:37:26 +01001632 tty_kref_put(tty);
Christoph Hellwigd5698c22007-02-10 01:46:46 -08001633}
1634
Alan Coxeeb89d92009-11-30 13:18:29 +00001635/**
Jiri Slaby955787ca2011-11-11 10:47:23 +01001636 * tty_release_checks - check a tty before real release
1637 * @tty: tty to check
Jiri Slaby955787ca2011-11-11 10:47:23 +01001638 * @idx: index of the tty
1639 *
1640 * Performs some paranoid checking before true release of the @tty.
1641 * This is a no-op unless TTY_PARANOIA_CHECK is defined.
1642 */
Peter Hurley359b9fb2014-11-05 12:12:59 -05001643static int tty_release_checks(struct tty_struct *tty, int idx)
Jiri Slaby955787ca2011-11-11 10:47:23 +01001644{
1645#ifdef TTY_PARANOIA_CHECK
1646 if (idx < 0 || idx >= tty->driver->num) {
Peter Hurleye2dfa3d2015-07-12 22:49:08 -04001647 tty_debug(tty, "bad idx %d\n", idx);
Jiri Slaby955787ca2011-11-11 10:47:23 +01001648 return -1;
1649 }
1650
1651 /* not much to check for devpts */
1652 if (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM)
1653 return 0;
1654
1655 if (tty != tty->driver->ttys[idx]) {
Peter Hurleye2dfa3d2015-07-12 22:49:08 -04001656 tty_debug(tty, "bad driver table[%d] = %p\n",
1657 idx, tty->driver->ttys[idx]);
Jiri Slaby955787ca2011-11-11 10:47:23 +01001658 return -1;
1659 }
Jiri Slaby955787ca2011-11-11 10:47:23 +01001660 if (tty->driver->other) {
Peter Hurley359b9fb2014-11-05 12:12:59 -05001661 struct tty_struct *o_tty = tty->link;
1662
Jiri Slaby955787ca2011-11-11 10:47:23 +01001663 if (o_tty != tty->driver->other->ttys[idx]) {
Peter Hurleye2dfa3d2015-07-12 22:49:08 -04001664 tty_debug(tty, "bad other table[%d] = %p\n",
1665 idx, tty->driver->other->ttys[idx]);
Jiri Slaby955787ca2011-11-11 10:47:23 +01001666 return -1;
1667 }
Jiri Slaby955787ca2011-11-11 10:47:23 +01001668 if (o_tty->link != tty) {
Peter Hurleye2dfa3d2015-07-12 22:49:08 -04001669 tty_debug(tty, "bad link = %p\n", o_tty->link);
Jiri Slaby955787ca2011-11-11 10:47:23 +01001670 return -1;
1671 }
1672 }
1673#endif
1674 return 0;
1675}
1676
1677/**
Okash Khawajaa09ac392017-07-20 08:22:36 +01001678 * tty_kclose - closes tty opened by tty_kopen
1679 * @tty: tty device
1680 *
1681 * Performs the final steps to release and free a tty device. It is the
1682 * same as tty_release_struct except that it also resets TTY_PORT_KOPENED
1683 * flag on tty->port.
1684 */
1685void tty_kclose(struct tty_struct *tty)
1686{
1687 /*
1688 * Ask the line discipline code to release its structures
1689 */
1690 tty_ldisc_release(tty);
1691
1692 /* Wait for pending work before tty destruction commmences */
1693 tty_flush_works(tty);
1694
1695 tty_debug_hangup(tty, "freeing structure\n");
1696 /*
1697 * The release_tty function takes care of the details of clearing
Eric Biggersed069822020-02-23 23:33:59 -08001698 * the slots and preserving the termios structure.
Okash Khawajaa09ac392017-07-20 08:22:36 +01001699 */
1700 mutex_lock(&tty_mutex);
1701 tty_port_set_kopened(tty->port, 0);
1702 release_tty(tty, tty->index);
1703 mutex_unlock(&tty_mutex);
1704}
1705EXPORT_SYMBOL_GPL(tty_kclose);
1706
1707/**
Rob Herring9ed90d22017-01-16 16:54:28 -06001708 * tty_release_struct - release a tty struct
1709 * @tty: tty device
1710 * @idx: index of the tty
1711 *
1712 * Performs the final steps to release and free a tty device. It is
1713 * roughly the reverse of tty_init_dev.
1714 */
1715void tty_release_struct(struct tty_struct *tty, int idx)
1716{
1717 /*
1718 * Ask the line discipline code to release its structures
1719 */
1720 tty_ldisc_release(tty);
1721
1722 /* Wait for pending work before tty destruction commmences */
1723 tty_flush_works(tty);
1724
1725 tty_debug_hangup(tty, "freeing structure\n");
1726 /*
1727 * The release_tty function takes care of the details of clearing
Eric Biggersed069822020-02-23 23:33:59 -08001728 * the slots and preserving the termios structure.
Rob Herring9ed90d22017-01-16 16:54:28 -06001729 */
1730 mutex_lock(&tty_mutex);
1731 release_tty(tty, idx);
1732 mutex_unlock(&tty_mutex);
1733}
1734EXPORT_SYMBOL_GPL(tty_release_struct);
1735
1736/**
Alan Coxeeb89d92009-11-30 13:18:29 +00001737 * tty_release - vfs callback for close
1738 * @inode: inode of tty
1739 * @filp: file pointer for handle to tty
1740 *
1741 * Called the last time each file handle is closed that references
1742 * this tty. There may however be several such references.
1743 *
1744 * Locking:
1745 * Takes bkl. See tty_release_dev
1746 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 * Even releasing the tty structures is a tricky business.. We have
1748 * to be very careful that the structures are all released at the
1749 * same time, as interrupts might otherwise get the wrong pointers.
1750 *
1751 * WSH 09/09/97: rewritten to avoid some nasty race conditions that could
1752 * lead to double frees or releasing memory still in use.
1753 */
Alan Coxeeb89d92009-11-30 13:18:29 +00001754
1755int tty_release(struct inode *inode, struct file *filp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756{
Nick Piggind996b622010-08-18 04:37:36 +10001757 struct tty_struct *tty = file_tty(filp);
Peter Hurley7ffb6da2014-11-05 12:13:00 -05001758 struct tty_struct *o_tty = NULL;
1759 int do_sleep, final;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 int idx;
Peter Hurley37b16452014-10-16 13:51:30 -04001761 long timeout = 0;
Peter Hurley494c1ea2014-10-16 13:54:36 -04001762 int once = 1;
Alan Cox37bdfb02008-02-08 04:18:47 -08001763
Jiri Slaby9de44bd2011-11-09 21:33:24 +01001764 if (tty_paranoia_check(tty, inode, __func__))
Alan Coxeeb89d92009-11-30 13:18:29 +00001765 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766
Alan Cox89c8d912012-08-08 16:30:13 +01001767 tty_lock(tty);
Jiri Slaby9de44bd2011-11-09 21:33:24 +01001768 check_tty_count(tty, __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
Arnd Bergmannec79d602010-06-01 22:53:01 +02001770 __tty_fasync(-1, filp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771
1772 idx = tty->index;
Peter Hurley7ffb6da2014-11-05 12:13:00 -05001773 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
1774 tty->driver->subtype == PTY_TYPE_MASTER)
1775 o_tty = tty->link;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776
Peter Hurley359b9fb2014-11-05 12:12:59 -05001777 if (tty_release_checks(tty, idx)) {
Alan Cox89c8d912012-08-08 16:30:13 +01001778 tty_unlock(tty);
Alan Coxeeb89d92009-11-30 13:18:29 +00001779 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781
Peter Hurleyd435cef2015-11-08 13:01:19 -05001782 tty_debug_hangup(tty, "releasing (count=%d)\n", tty->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783
Alan Coxf34d7a52008-04-30 00:54:13 -07001784 if (tty->ops->close)
1785 tty->ops->close(tty, filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786
Peter Hurley2aff5e22014-11-05 12:13:01 -05001787 /* If tty is pty master, lock the slave pty (stable lock order) */
1788 tty_lock_slave(o_tty);
1789
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 /*
1791 * Sanity check: if tty->count is going to zero, there shouldn't be
1792 * any waiters on tty->read_wait or tty->write_wait. We test the
1793 * wait queues and kick everyone out _before_ actually starting to
1794 * close. This ensures that we won't block while releasing the tty
1795 * structure.
1796 *
1797 * The test for the o_tty closing is necessary, since the master and
1798 * slave sides may close in any order. If the slave side closes out
1799 * first, its count will be one, since the master side holds an open.
Peter Hurley324c1652014-11-05 12:12:56 -05001800 * Thus this test wouldn't be triggered at the time the slave closed,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 * so we do it now.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 */
1803 while (1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 do_sleep = 0;
1805
Peter Hurley324c1652014-11-05 12:12:56 -05001806 if (tty->count <= 1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807 if (waitqueue_active(&tty->read_wait)) {
Linus Torvaldsa9a08842018-02-11 14:34:03 -08001808 wake_up_poll(&tty->read_wait, EPOLLIN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 do_sleep++;
1810 }
1811 if (waitqueue_active(&tty->write_wait)) {
Linus Torvaldsa9a08842018-02-11 14:34:03 -08001812 wake_up_poll(&tty->write_wait, EPOLLOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 do_sleep++;
1814 }
1815 }
Peter Hurley7ffb6da2014-11-05 12:13:00 -05001816 if (o_tty && o_tty->count <= 1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 if (waitqueue_active(&o_tty->read_wait)) {
Linus Torvaldsa9a08842018-02-11 14:34:03 -08001818 wake_up_poll(&o_tty->read_wait, EPOLLIN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819 do_sleep++;
1820 }
1821 if (waitqueue_active(&o_tty->write_wait)) {
Linus Torvaldsa9a08842018-02-11 14:34:03 -08001822 wake_up_poll(&o_tty->write_wait, EPOLLOUT);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 do_sleep++;
1824 }
1825 }
1826 if (!do_sleep)
1827 break;
1828
Peter Hurley494c1ea2014-10-16 13:54:36 -04001829 if (once) {
1830 once = 0;
Peter Hurley339f36b2015-11-08 13:01:13 -05001831 tty_warn(tty, "read/write wait queue active!\n");
Peter Hurley494c1ea2014-10-16 13:54:36 -04001832 }
Peter Hurley37b16452014-10-16 13:51:30 -04001833 schedule_timeout_killable(timeout);
1834 if (timeout < 120 * HZ)
1835 timeout = 2 * timeout + 1;
1836 else
1837 timeout = MAX_SCHEDULE_TIMEOUT;
Alan Cox37bdfb02008-02-08 04:18:47 -08001838 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839
Peter Hurley7ffb6da2014-11-05 12:13:00 -05001840 if (o_tty) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 if (--o_tty->count < 0) {
Peter Hurley339f36b2015-11-08 13:01:13 -05001842 tty_warn(tty, "bad slave count (%d)\n", o_tty->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 o_tty->count = 0;
1844 }
1845 }
1846 if (--tty->count < 0) {
Peter Hurley339f36b2015-11-08 13:01:13 -05001847 tty_warn(tty, "bad tty->count (%d)\n", tty->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 tty->count = 0;
1849 }
Alan Cox37bdfb02008-02-08 04:18:47 -08001850
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851 /*
1852 * We've decremented tty->count, so we need to remove this file
1853 * descriptor off the tty->tty_files list; this serves two
1854 * purposes:
1855 * - check_tty_count sees the correct number of file descriptors
1856 * associated with this tty.
1857 * - do_tty_hangup no longer sees this file descriptor as
1858 * something that needs to be handled for hangups.
1859 */
Nick Piggind996b622010-08-18 04:37:36 +10001860 tty_del_file(filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861
1862 /*
1863 * Perform some housekeeping before deciding whether to return.
1864 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 * If _either_ side is closing, make sure there aren't any
1866 * processes that still think tty or o_tty is their controlling
1867 * tty.
1868 */
Peter Hurley324c1652014-11-05 12:12:56 -05001869 if (!tty->count) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 read_lock(&tasklist_lock);
Jiri Slaby64d608d2021-05-05 11:19:06 +02001871 session_clear_tty(tty->ctrl.session);
Peter Hurley7ffb6da2014-11-05 12:13:00 -05001872 if (o_tty)
Jiri Slaby64d608d2021-05-05 11:19:06 +02001873 session_clear_tty(o_tty->ctrl.session);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874 read_unlock(&tasklist_lock);
1875 }
1876
Peter Hurley324c1652014-11-05 12:12:56 -05001877 /* check whether both sides are closing ... */
Peter Hurley7ffb6da2014-11-05 12:13:00 -05001878 final = !tty->count && !(o_tty && o_tty->count);
Peter Hurley324c1652014-11-05 12:12:56 -05001879
Peter Hurley2aff5e22014-11-05 12:13:01 -05001880 tty_unlock_slave(o_tty);
1881 tty_unlock(tty);
1882
Peter Hurley04980702014-11-05 12:12:52 -05001883 /* At this point, the tty->count == 0 should ensure a dead tty
Xiaofei Tanb426a5b2021-05-12 17:26:18 +08001884 * cannot be re-opened by a racing opener.
1885 */
Paul Fulghumda965822006-02-14 13:53:00 -08001886
Peter Hurley324c1652014-11-05 12:12:56 -05001887 if (!final)
Alan Coxeeb89d92009-11-30 13:18:29 +00001888 return 0;
Alan Cox37bdfb02008-02-08 04:18:47 -08001889
Peter Hurleyaccff792015-07-12 22:49:09 -04001890 tty_debug_hangup(tty, "final close\n");
Peter Hurleya2965b72013-03-11 16:44:35 -04001891
Rob Herring9ed90d22017-01-16 16:54:28 -06001892 tty_release_struct(tty, idx);
Alan Coxeeb89d92009-11-30 13:18:29 +00001893 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894}
1895
Alan Coxaf9b8972006-08-27 01:24:01 -07001896/**
Peter Hurley52494ee2014-11-05 12:12:50 -05001897 * tty_open_current_tty - get locked tty of current task
Jiri Slabyb82154a2011-11-09 21:33:19 +01001898 * @device: device number
1899 * @filp: file pointer to tty
Peter Hurley52494ee2014-11-05 12:12:50 -05001900 * @return: locked tty of the current task iff @device is /dev/tty
1901 *
1902 * Performs a re-open of the current task's controlling tty.
Jiri Slabyb82154a2011-11-09 21:33:19 +01001903 *
1904 * We cannot return driver and index like for the other nodes because
1905 * devpts will not work then. It expects inodes to be from devpts FS.
1906 */
1907static struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp)
1908{
1909 struct tty_struct *tty;
Peter Hurley52494ee2014-11-05 12:12:50 -05001910 int retval;
Jiri Slabyb82154a2011-11-09 21:33:19 +01001911
1912 if (device != MKDEV(TTYAUX_MAJOR, 0))
1913 return NULL;
1914
1915 tty = get_current_tty();
1916 if (!tty)
1917 return ERR_PTR(-ENXIO);
1918
1919 filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */
1920 /* noctty = 1; */
Peter Hurley52494ee2014-11-05 12:12:50 -05001921 tty_lock(tty);
1922 tty_kref_put(tty); /* safe to drop the kref now */
1923
1924 retval = tty_reopen(tty);
1925 if (retval < 0) {
1926 tty_unlock(tty);
1927 tty = ERR_PTR(retval);
1928 }
Jiri Slabyb82154a2011-11-09 21:33:19 +01001929 return tty;
1930}
1931
1932/**
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001933 * tty_lookup_driver - lookup a tty driver for a given device file
1934 * @device: device number
1935 * @filp: file pointer to tty
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001936 * @index: index for the device in the @return driver
1937 * @return: driver for this inode (with increased refcount)
1938 *
Xiaofei Tan395e7832021-05-12 17:26:14 +08001939 * If @return is not erroneous, the caller is responsible to decrement the
1940 * refcount by tty_driver_kref_put.
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001941 *
1942 * Locking: tty_mutex protects get_tty_driver
1943 */
1944static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp,
Peter Hurley11e1d4a2016-01-09 21:13:52 -08001945 int *index)
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001946{
Lin Yi8c8af412019-05-10 12:22:57 +08001947 struct tty_driver *driver = NULL;
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001948
Jiri Slaby2cd00502011-11-09 21:33:22 +01001949 switch (device) {
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001950#ifdef CONFIG_VT
Jiri Slaby2cd00502011-11-09 21:33:22 +01001951 case MKDEV(TTY_MAJOR, 0): {
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001952 extern struct tty_driver *console_driver;
Xiaofei Tane73b2402021-05-12 17:26:15 +08001953
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001954 driver = tty_driver_kref_get(console_driver);
1955 *index = fg_console;
Jiri Slaby2cd00502011-11-09 21:33:22 +01001956 break;
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001957 }
1958#endif
Jiri Slaby2cd00502011-11-09 21:33:22 +01001959 case MKDEV(TTYAUX_MAJOR, 1): {
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001960 struct tty_driver *console_driver = console_device(index);
Xiaofei Tane73b2402021-05-12 17:26:15 +08001961
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001962 if (console_driver) {
1963 driver = tty_driver_kref_get(console_driver);
Okash Khawaja12e84c72017-05-15 18:45:32 +01001964 if (driver && filp) {
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001965 /* Don't let /dev/console block */
1966 filp->f_flags |= O_NONBLOCK;
Jiri Slaby2cd00502011-11-09 21:33:22 +01001967 break;
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001968 }
1969 }
Lin Yi8c8af412019-05-10 12:22:57 +08001970 if (driver)
1971 tty_driver_kref_put(driver);
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001972 return ERR_PTR(-ENODEV);
1973 }
Jiri Slaby2cd00502011-11-09 21:33:22 +01001974 default:
1975 driver = get_tty_driver(device, index);
1976 if (!driver)
1977 return ERR_PTR(-ENODEV);
1978 break;
1979 }
Jiri Slaby5b5e7042011-11-09 21:33:20 +01001980 return driver;
1981}
1982
Uwe Kleine-König4ea3cd62020-12-18 11:42:44 +01001983static struct tty_struct *tty_kopen(dev_t device, int shared)
Okash Khawajaa09ac392017-07-20 08:22:36 +01001984{
1985 struct tty_struct *tty;
Uwe Kleine-Königf1d31742019-12-17 08:50:40 +01001986 struct tty_driver *driver;
Okash Khawajaa09ac392017-07-20 08:22:36 +01001987 int index = -1;
1988
1989 mutex_lock(&tty_mutex);
1990 driver = tty_lookup_driver(device, NULL, &index);
1991 if (IS_ERR(driver)) {
1992 mutex_unlock(&tty_mutex);
1993 return ERR_CAST(driver);
1994 }
1995
1996 /* check whether we're reopening an existing tty */
1997 tty = tty_driver_lookup_tty(driver, NULL, index);
Uwe Kleine-König4ea3cd62020-12-18 11:42:44 +01001998 if (IS_ERR(tty) || shared)
Okash Khawajaa09ac392017-07-20 08:22:36 +01001999 goto out;
2000
2001 if (tty) {
2002 /* drop kref from tty_driver_lookup_tty() */
2003 tty_kref_put(tty);
2004 tty = ERR_PTR(-EBUSY);
2005 } else { /* tty_init_dev returns tty with the tty_lock held */
2006 tty = tty_init_dev(driver, index);
2007 if (IS_ERR(tty))
2008 goto out;
2009 tty_port_set_kopened(tty->port, 1);
2010 }
2011out:
2012 mutex_unlock(&tty_mutex);
2013 tty_driver_kref_put(driver);
2014 return tty;
2015}
Uwe Kleine-König4ea3cd62020-12-18 11:42:44 +01002016
2017/**
2018 * tty_kopen_exclusive - open a tty device for kernel
2019 * @device: dev_t of device to open
2020 *
2021 * Opens tty exclusively for kernel. Performs the driver lookup,
2022 * makes sure it's not already opened and performs the first-time
2023 * tty initialization.
2024 *
2025 * Returns the locked initialized &tty_struct
2026 *
2027 * Claims the global tty_mutex to serialize:
2028 * - concurrent first-time tty initialization
2029 * - concurrent tty driver removal w/ lookup
2030 * - concurrent tty removal from driver table
2031 */
2032struct tty_struct *tty_kopen_exclusive(dev_t device)
2033{
2034 return tty_kopen(device, 0);
2035}
2036EXPORT_SYMBOL_GPL(tty_kopen_exclusive);
2037
2038/**
2039 * tty_kopen_shared - open a tty device for shared in-kernel use
2040 * @device: dev_t of device to open
2041 *
2042 * Opens an already existing tty for in-kernel use. Compared to
2043 * tty_kopen_exclusive() above it doesn't ensure to be the only user.
2044 *
2045 * Locking is identical to tty_kopen() above.
2046 */
2047struct tty_struct *tty_kopen_shared(dev_t device)
2048{
2049 return tty_kopen(device, 1);
2050}
2051EXPORT_SYMBOL_GPL(tty_kopen_shared);
Okash Khawajaa09ac392017-07-20 08:22:36 +01002052
2053/**
Peter Hurleyd6203d02016-01-09 21:13:53 -08002054 * tty_open_by_driver - open a tty device
2055 * @device: dev_t of device to open
Peter Hurleyd6203d02016-01-09 21:13:53 -08002056 * @filp: file pointer to tty
2057 *
2058 * Performs the driver lookup, checks for a reopen, or otherwise
2059 * performs the first-time tty initialization.
2060 *
2061 * Returns the locked initialized or re-opened &tty_struct
2062 *
2063 * Claims the global tty_mutex to serialize:
2064 * - concurrent first-time tty initialization
2065 * - concurrent tty driver removal w/ lookup
2066 * - concurrent tty removal from driver table
2067 */
Sudip Mukherjee14ce3842019-11-20 15:17:08 +00002068static struct tty_struct *tty_open_by_driver(dev_t device,
Peter Hurleyd6203d02016-01-09 21:13:53 -08002069 struct file *filp)
2070{
2071 struct tty_struct *tty;
2072 struct tty_driver *driver = NULL;
2073 int index = -1;
2074 int retval;
2075
2076 mutex_lock(&tty_mutex);
2077 driver = tty_lookup_driver(device, filp, &index);
2078 if (IS_ERR(driver)) {
2079 mutex_unlock(&tty_mutex);
2080 return ERR_CAST(driver);
2081 }
2082
2083 /* check whether we're reopening an existing tty */
Linus Torvalds8ead9dd2016-04-25 20:04:08 -07002084 tty = tty_driver_lookup_tty(driver, filp, index);
Peter Hurleyd6203d02016-01-09 21:13:53 -08002085 if (IS_ERR(tty)) {
2086 mutex_unlock(&tty_mutex);
2087 goto out;
2088 }
2089
2090 if (tty) {
Okash Khawajaa09ac392017-07-20 08:22:36 +01002091 if (tty_port_kopened(tty->port)) {
2092 tty_kref_put(tty);
2093 mutex_unlock(&tty_mutex);
2094 tty = ERR_PTR(-EBUSY);
2095 goto out;
2096 }
Peter Hurleyd6203d02016-01-09 21:13:53 -08002097 mutex_unlock(&tty_mutex);
2098 retval = tty_lock_interruptible(tty);
Peter Hurley5e00bbf2016-03-31 17:47:07 -07002099 tty_kref_put(tty); /* drop kref from tty_driver_lookup_tty() */
Peter Hurleyd6203d02016-01-09 21:13:53 -08002100 if (retval) {
2101 if (retval == -EINTR)
2102 retval = -ERESTARTSYS;
2103 tty = ERR_PTR(retval);
2104 goto out;
2105 }
Peter Hurleyd6203d02016-01-09 21:13:53 -08002106 retval = tty_reopen(tty);
2107 if (retval < 0) {
2108 tty_unlock(tty);
2109 tty = ERR_PTR(retval);
2110 }
2111 } else { /* Returns with the tty_lock held for now */
2112 tty = tty_init_dev(driver, index);
2113 mutex_unlock(&tty_mutex);
2114 }
2115out:
2116 tty_driver_kref_put(driver);
2117 return tty;
2118}
2119
2120/**
Alan Coxeeb89d92009-11-30 13:18:29 +00002121 * tty_open - open a tty device
Alan Coxaf9b8972006-08-27 01:24:01 -07002122 * @inode: inode of device file
2123 * @filp: file pointer to tty
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124 *
Alan Coxaf9b8972006-08-27 01:24:01 -07002125 * tty_open and tty_release keep up the tty count that contains the
2126 * number of opens done on a tty. We cannot use the inode-count, as
2127 * different inodes might point to the same tty.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128 *
Alan Coxaf9b8972006-08-27 01:24:01 -07002129 * Open-counting is needed for pty masters, as well as for keeping
2130 * track of serial lines: DTR is dropped when the last close happens.
2131 * (This is not done solely through tty->count, now. - Ted 1/27/92)
2132 *
2133 * The termios state of a pty is reset on first open so that
2134 * settings don't persist across reuse.
2135 *
Jiri Slaby5b5e7042011-11-09 21:33:20 +01002136 * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev.
Peter Zijlstra24ec8392006-12-08 02:36:04 -08002137 * tty->count should protect the rest.
2138 * ->siglock protects ->signal/->sighand
Alan Cox89c8d912012-08-08 16:30:13 +01002139 *
2140 * Note: the tty_unlock/lock cases without a ref are only safe due to
2141 * tty_mutex
Linus Torvalds1da177e2005-04-16 15:20:36 -07002142 */
Alan Coxaf9b8972006-08-27 01:24:01 -07002143
Alan Coxeeb89d92009-11-30 13:18:29 +00002144static int tty_open(struct inode *inode, struct file *filp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145{
Jiri Slabyb82154a2011-11-09 21:33:19 +01002146 struct tty_struct *tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002147 int noctty, retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148 dev_t device = inode->i_rdev;
Andrew Morton846c1512009-04-02 16:56:36 -07002149 unsigned saved_flags = filp->f_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002150
2151 nonseekable_open(inode, filp);
Alan Cox37bdfb02008-02-08 04:18:47 -08002152
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153retry_open:
Jiri Slabyfa90e1c2011-10-12 11:32:43 +02002154 retval = tty_alloc_file(filp);
2155 if (retval)
2156 return -ENOMEM;
2157
Jiri Slabyb82154a2011-11-09 21:33:19 +01002158 tty = tty_open_current_tty(device, filp);
Peter Hurleyd6203d02016-01-09 21:13:53 -08002159 if (!tty)
Sudip Mukherjee14ce3842019-11-20 15:17:08 +00002160 tty = tty_open_by_driver(device, filp);
Sukadev Bhattiprolu4a2b5fd2008-10-13 10:42:49 +01002161
Alan Coxeeb89d92009-11-30 13:18:29 +00002162 if (IS_ERR(tty)) {
Peter Hurleyd6203d02016-01-09 21:13:53 -08002163 tty_free_file(filp);
Jiri Slabyba5db442011-11-09 21:33:21 +01002164 retval = PTR_ERR(tty);
Peter Hurley7f22f6c2016-01-09 21:13:45 -08002165 if (retval != -EAGAIN || signal_pending(current))
Peter Hurleyd6203d02016-01-09 21:13:53 -08002166 return retval;
Peter Hurley7f22f6c2016-01-09 21:13:45 -08002167 schedule();
2168 goto retry_open;
Alan Coxeeb89d92009-11-30 13:18:29 +00002169 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170
Jiri Slabyfa90e1c2011-10-12 11:32:43 +02002171 tty_add_file(tty, filp);
Nick Piggind996b622010-08-18 04:37:36 +10002172
Jiri Slaby9de44bd2011-11-09 21:33:24 +01002173 check_tty_count(tty, __func__);
Peter Hurleyd435cef2015-11-08 13:01:19 -05002174 tty_debug_hangup(tty, "opening (count=%d)\n", tty->count);
Peter Hurleyaccff792015-07-12 22:49:09 -04002175
Herton Ronaldo Krzesinski909bc772011-03-31 15:35:31 -03002176 if (tty->ops->open)
2177 retval = tty->ops->open(tty, filp);
2178 else
2179 retval = -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002180 filp->f_flags = saved_flags;
2181
Linus Torvalds1da177e2005-04-16 15:20:36 -07002182 if (retval) {
Peter Hurleyd435cef2015-11-08 13:01:19 -05002183 tty_debug_hangup(tty, "open error %d, releasing\n", retval);
Peter Hurleyaccff792015-07-12 22:49:09 -04002184
Alan Cox89c8d912012-08-08 16:30:13 +01002185 tty_unlock(tty); /* need to call tty_release without BTM */
Alan Coxeeb89d92009-11-30 13:18:29 +00002186 tty_release(inode, filp);
Arnd Bergmann64ba3dc32010-06-01 22:53:02 +02002187 if (retval != -ERESTARTSYS)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002188 return retval;
Arnd Bergmann64ba3dc32010-06-01 22:53:02 +02002189
2190 if (signal_pending(current))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191 return retval;
Arnd Bergmann64ba3dc32010-06-01 22:53:02 +02002192
Linus Torvalds1da177e2005-04-16 15:20:36 -07002193 schedule();
2194 /*
2195 * Need to reset f_op in case a hangup happened.
2196 */
Peter Hurley12569372014-11-05 12:26:24 -05002197 if (tty_hung_up_p(filp))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002198 filp->f_op = &tty_fops;
2199 goto retry_open;
2200 }
Peter Hurleyd4855e12013-11-19 08:46:27 -05002201 clear_bit(TTY_HUPPED, &tty->flags);
Alan Coxeeb89d92009-11-30 13:18:29 +00002202
Peter Hurley11e1d4a2016-01-09 21:13:52 -08002203 noctty = (filp->f_flags & O_NOCTTY) ||
Nicolas Pitrea1235b32017-04-12 18:37:16 -04002204 (IS_ENABLED(CONFIG_VT) && device == MKDEV(TTY_MAJOR, 0)) ||
2205 device == MKDEV(TTYAUX_MAJOR, 1) ||
2206 (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
2207 tty->driver->subtype == PTY_TYPE_MASTER);
2208 if (!noctty)
2209 tty_open_proc_set_tty(filp, tty);
Alan Cox89c8d912012-08-08 16:30:13 +01002210 tty_unlock(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211 return 0;
2212}
2213
Jonathan Corbet39d95b92008-05-16 09:10:50 -06002214
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215
Alan Coxaf9b8972006-08-27 01:24:01 -07002216/**
2217 * tty_poll - check tty status
2218 * @filp: file being polled
2219 * @wait: poll wait structures to update
2220 *
2221 * Call the line discipline polling method to obtain the poll
2222 * status of the device.
2223 *
2224 * Locking: locks called line discipline but ldisc poll method
2225 * may be re-entered freely by other callers.
2226 */
2227
Al Viroafc9a422017-07-03 06:39:46 -04002228static __poll_t tty_poll(struct file *filp, poll_table *wait)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002229{
Nick Piggind996b622010-08-18 04:37:36 +10002230 struct tty_struct *tty = file_tty(filp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002231 struct tty_ldisc *ld;
Al Viroe6c8adc2017-07-03 22:25:56 -04002232 __poll_t ret = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233
Al Viro6131ffa2013-02-27 16:59:05 -05002234 if (tty_paranoia_check(tty, file_inode(filp), "tty_poll"))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235 return 0;
Alan Cox37bdfb02008-02-08 04:18:47 -08002236
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237 ld = tty_ldisc_ref_wait(tty);
Peter Hurleye55afd12016-01-10 22:41:01 -08002238 if (!ld)
2239 return hung_up_tty_poll(filp, wait);
Alan Coxa352def2008-07-16 21:53:12 +01002240 if (ld->ops->poll)
Peter Hurleyc961bfb2014-11-05 12:26:25 -05002241 ret = ld->ops->poll(tty, filp, wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242 tty_ldisc_deref(ld);
2243 return ret;
2244}
2245
Arnd Bergmannec79d602010-06-01 22:53:01 +02002246static int __tty_fasync(int fd, struct file *filp, int on)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247{
Nick Piggind996b622010-08-18 04:37:36 +10002248 struct tty_struct *tty = file_tty(filp);
Alan Cox47f86832008-04-30 00:53:30 -07002249 unsigned long flags;
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06002250 int retval = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251
Al Viro6131ffa2013-02-27 16:59:05 -05002252 if (tty_paranoia_check(tty, file_inode(filp), "tty_fasync"))
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06002253 goto out;
Alan Cox37bdfb02008-02-08 04:18:47 -08002254
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 retval = fasync_helper(fd, filp, on, &tty->fasync);
2256 if (retval <= 0)
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06002257 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258
2259 if (on) {
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002260 enum pid_type type;
2261 struct pid *pid;
Peter Hurleyf6c8dbe2013-06-15 07:28:28 -04002262
Jiri Slaby64d608d2021-05-05 11:19:06 +02002263 spin_lock_irqsave(&tty->ctrl.lock, flags);
2264 if (tty->ctrl.pgrp) {
2265 pid = tty->ctrl.pgrp;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002266 type = PIDTYPE_PGID;
2267 } else {
2268 pid = task_pid(current);
Eric W. Biederman01919132017-07-16 22:05:57 -05002269 type = PIDTYPE_TGID;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08002270 }
Linus Torvalds80e1e822010-02-07 10:11:23 -08002271 get_pid(pid);
Jiri Slaby64d608d2021-05-05 11:19:06 +02002272 spin_unlock_irqrestore(&tty->ctrl.lock, flags);
Jeff Laytone0b93ed2014-08-22 11:27:32 -04002273 __f_setown(filp, pid, type, 0);
Linus Torvalds80e1e822010-02-07 10:11:23 -08002274 put_pid(pid);
Jeff Laytone0b93ed2014-08-22 11:27:32 -04002275 retval = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276 }
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06002277out:
Arnd Bergmannec79d602010-06-01 22:53:01 +02002278 return retval;
2279}
2280
2281static int tty_fasync(int fd, struct file *filp, int on)
2282{
Alan Cox89c8d912012-08-08 16:30:13 +01002283 struct tty_struct *tty = file_tty(filp);
Peter Hurleya8f3a292016-01-09 21:45:11 -08002284 int retval = -ENOTTY;
Alan Cox89c8d912012-08-08 16:30:13 +01002285
2286 tty_lock(tty);
Peter Hurleya8f3a292016-01-09 21:45:11 -08002287 if (!tty_hung_up_p(filp))
2288 retval = __tty_fasync(fd, filp, on);
Alan Cox89c8d912012-08-08 16:30:13 +01002289 tty_unlock(tty);
2290
Jonathan Corbet5d1e3232008-06-19 16:04:53 -06002291 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292}
2293
Alan Coxaf9b8972006-08-27 01:24:01 -07002294/**
2295 * tiocsti - fake input character
2296 * @tty: tty to fake input into
2297 * @p: pointer to character
2298 *
Robert P. J. Day3a4fa0a2007-10-19 23:10:43 +02002299 * Fake input to a tty device. Does the necessary locking and
Alan Coxaf9b8972006-08-27 01:24:01 -07002300 * input management.
2301 *
2302 * FIXME: does not honour flow control ??
2303 *
2304 * Locking:
Peter Hurley137084b2013-06-15 07:04:46 -04002305 * Called functions take tty_ldiscs_lock
Alan Coxaf9b8972006-08-27 01:24:01 -07002306 * current->signal->tty check is safe without locks
Alan Cox28298232006-09-29 02:00:58 -07002307 *
2308 * FIXME: may race normal receive processing
Alan Coxaf9b8972006-08-27 01:24:01 -07002309 */
2310
Linus Torvalds1da177e2005-04-16 15:20:36 -07002311static int tiocsti(struct tty_struct *tty, char __user *p)
2312{
2313 char ch, mbz = 0;
2314 struct tty_ldisc *ld;
Alan Cox37bdfb02008-02-08 04:18:47 -08002315
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316 if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
2317 return -EPERM;
2318 if (get_user(ch, p))
2319 return -EFAULT;
Al Viro1e641742008-12-09 09:23:33 +00002320 tty_audit_tiocsti(tty, ch);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321 ld = tty_ldisc_ref_wait(tty);
Peter Hurleye55afd12016-01-10 22:41:01 -08002322 if (!ld)
2323 return -EIO;
Greg Kroah-Hartman27cfb3a2019-01-20 10:46:58 +01002324 if (ld->ops->receive_buf)
2325 ld->ops->receive_buf(tty, &ch, &mbz, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326 tty_ldisc_deref(ld);
2327 return 0;
2328}
2329
Alan Coxaf9b8972006-08-27 01:24:01 -07002330/**
2331 * tiocgwinsz - implement window query ioctl
Jiri Slabyfa441952020-08-18 10:56:51 +02002332 * @tty: tty
Alan Coxaf9b8972006-08-27 01:24:01 -07002333 * @arg: user buffer for result
2334 *
Alan Cox808a0d32006-09-29 02:00:40 -07002335 * Copies the kernel idea of the window size into the user buffer.
Alan Coxaf9b8972006-08-27 01:24:01 -07002336 *
Peter Hurleydee4a0b2013-07-24 16:43:51 -04002337 * Locking: tty->winsize_mutex is taken to ensure the winsize data
Alan Cox808a0d32006-09-29 02:00:40 -07002338 * is consistent.
Alan Coxaf9b8972006-08-27 01:24:01 -07002339 */
2340
Alan Cox37bdfb02008-02-08 04:18:47 -08002341static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342{
Alan Cox808a0d32006-09-29 02:00:40 -07002343 int err;
2344
Peter Hurleydee4a0b2013-07-24 16:43:51 -04002345 mutex_lock(&tty->winsize_mutex);
Alan Cox808a0d32006-09-29 02:00:40 -07002346 err = copy_to_user(arg, &tty->winsize, sizeof(*arg));
Peter Hurleydee4a0b2013-07-24 16:43:51 -04002347 mutex_unlock(&tty->winsize_mutex);
Alan Cox808a0d32006-09-29 02:00:40 -07002348
Xiaofei Tan94bc2eb2021-05-12 17:26:16 +08002349 return err ? -EFAULT : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002350}
2351
Alan Coxaf9b8972006-08-27 01:24:01 -07002352/**
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002353 * tty_do_resize - resize event
2354 * @tty: tty being resized
Jiri Slabyfa441952020-08-18 10:56:51 +02002355 * @ws: new dimensions
Alan Coxaf9b8972006-08-27 01:24:01 -07002356 *
Daniel Mack3ad2f3fb2010-02-03 08:01:28 +08002357 * Update the termios variables and send the necessary signals to
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002358 * peform a terminal resize correctly
Alan Coxaf9b8972006-08-27 01:24:01 -07002359 */
2360
Alan Coxfc6f6232009-01-02 13:43:17 +00002361int tty_do_resize(struct tty_struct *tty, struct winsize *ws)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362{
Alan Coxfc6f6232009-01-02 13:43:17 +00002363 struct pid *pgrp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364
Alan Coxfc6f6232009-01-02 13:43:17 +00002365 /* Lock the tty */
Peter Hurleydee4a0b2013-07-24 16:43:51 -04002366 mutex_lock(&tty->winsize_mutex);
Alan Coxfc6f6232009-01-02 13:43:17 +00002367 if (!memcmp(ws, &tty->winsize, sizeof(*ws)))
Alan Coxca9bda02006-09-29 02:00:03 -07002368 goto done;
Alan Cox47f86832008-04-30 00:53:30 -07002369
Peter Hurley5b239542014-10-16 14:59:45 -04002370 /* Signal the foreground process group */
2371 pgrp = tty_get_pgrp(tty);
Alan Cox47f86832008-04-30 00:53:30 -07002372 if (pgrp)
2373 kill_pgrp(pgrp, SIGWINCH, 1);
Alan Cox47f86832008-04-30 00:53:30 -07002374 put_pid(pgrp);
Alan Cox47f86832008-04-30 00:53:30 -07002375
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002376 tty->winsize = *ws;
Alan Coxca9bda02006-09-29 02:00:03 -07002377done:
Peter Hurleydee4a0b2013-07-24 16:43:51 -04002378 mutex_unlock(&tty->winsize_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379 return 0;
2380}
Martin Schwidefsky4d334fd2013-01-04 14:55:13 +01002381EXPORT_SYMBOL(tty_do_resize);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382
Alan Coxaf9b8972006-08-27 01:24:01 -07002383/**
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002384 * tiocswinsz - implement window size set ioctl
Jiri Slabyfa441952020-08-18 10:56:51 +02002385 * @tty: tty side of tty
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002386 * @arg: user buffer for result
2387 *
2388 * Copies the user idea of the window size to the kernel. Traditionally
2389 * this is just advisory information but for the Linux console it
2390 * actually has driver level meaning and triggers a VC resize.
2391 *
2392 * Locking:
Lucas De Marchi25985ed2011-03-30 22:57:33 -03002393 * Driver dependent. The default do_resize method takes the
Jiri Slaby64d608d2021-05-05 11:19:06 +02002394 * tty termios mutex and ctrl.lock. The console takes its own lock
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002395 * then calls into the default method.
2396 */
2397
Alan Coxfc6f6232009-01-02 13:43:17 +00002398static int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg)
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002399{
2400 struct winsize tmp_ws;
Xiaofei Tane73b2402021-05-12 17:26:15 +08002401
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002402 if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
2403 return -EFAULT;
2404
2405 if (tty->ops->resize)
Alan Coxfc6f6232009-01-02 13:43:17 +00002406 return tty->ops->resize(tty, &tmp_ws);
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002407 else
Alan Coxfc6f6232009-01-02 13:43:17 +00002408 return tty_do_resize(tty, &tmp_ws);
Alan Cox8c9a9dd2008-08-15 10:39:38 +01002409}
2410
2411/**
Alan Coxaf9b8972006-08-27 01:24:01 -07002412 * tioccons - allow admin to move logical console
2413 * @file: the file to become console
2414 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -03002415 * Allow the administrator to move the redirected console device
Alan Coxaf9b8972006-08-27 01:24:01 -07002416 *
2417 * Locking: uses redirect_lock to guard the redirect information
2418 */
2419
Linus Torvalds1da177e2005-04-16 15:20:36 -07002420static int tioccons(struct file *file)
2421{
2422 if (!capable(CAP_SYS_ADMIN))
2423 return -EPERM;
Linus Torvalds9bb48c82021-01-19 11:41:16 -08002424 if (file->f_op->write_iter == redirected_tty_write) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002425 struct file *f;
Xiaofei Tane73b2402021-05-12 17:26:15 +08002426
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427 spin_lock(&redirect_lock);
2428 f = redirect;
2429 redirect = NULL;
2430 spin_unlock(&redirect_lock);
2431 if (f)
2432 fput(f);
2433 return 0;
2434 }
Linus Torvaldsa9cbbb82021-01-29 12:28:20 -08002435 if (file->f_op->write_iter != tty_write)
2436 return -ENOTTY;
2437 if (!(file->f_mode & FMODE_WRITE))
2438 return -EBADF;
2439 if (!(file->f_mode & FMODE_CAN_WRITE))
2440 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441 spin_lock(&redirect_lock);
2442 if (redirect) {
2443 spin_unlock(&redirect_lock);
2444 return -EBUSY;
2445 }
Al Virocb0942b2012-08-27 14:48:26 -04002446 redirect = get_file(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002447 spin_unlock(&redirect_lock);
2448 return 0;
2449}
2450
Alan Coxaf9b8972006-08-27 01:24:01 -07002451/**
Alan Coxaf9b8972006-08-27 01:24:01 -07002452 * tiocsetd - set line discipline
2453 * @tty: tty device
2454 * @p: pointer to user data
2455 *
2456 * Set the line discipline according to user request.
2457 *
2458 * Locking: see tty_set_ldisc, this function is just a helper
2459 */
2460
Linus Torvalds1da177e2005-04-16 15:20:36 -07002461static int tiocsetd(struct tty_struct *tty, int __user *p)
2462{
Peter Hurleyc12da962016-01-10 22:41:04 -08002463 int disc;
Alan Cox04f378b2008-04-30 00:53:29 -07002464 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002465
Peter Hurleyc12da962016-01-10 22:41:04 -08002466 if (get_user(disc, p))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002467 return -EFAULT;
Alan Cox04f378b2008-04-30 00:53:29 -07002468
Peter Hurleyc12da962016-01-10 22:41:04 -08002469 ret = tty_set_ldisc(tty, disc);
Alan Cox04f378b2008-04-30 00:53:29 -07002470
2471 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002472}
2473
Alan Coxaf9b8972006-08-27 01:24:01 -07002474/**
Peter Hurley5c17c862016-01-10 22:40:55 -08002475 * tiocgetd - get line discipline
2476 * @tty: tty device
2477 * @p: pointer to user data
2478 *
2479 * Retrieves the line discipline id directly from the ldisc.
2480 *
2481 * Locking: waits for ldisc reference (in case the line discipline
2482 * is changing or the tty is being hungup)
2483 */
2484
2485static int tiocgetd(struct tty_struct *tty, int __user *p)
2486{
2487 struct tty_ldisc *ld;
2488 int ret;
2489
2490 ld = tty_ldisc_ref_wait(tty);
Peter Hurleye55afd12016-01-10 22:41:01 -08002491 if (!ld)
2492 return -EIO;
Peter Hurley5c17c862016-01-10 22:40:55 -08002493 ret = put_user(ld->ops->num, p);
2494 tty_ldisc_deref(ld);
2495 return ret;
2496}
2497
2498/**
Alan Coxaf9b8972006-08-27 01:24:01 -07002499 * send_break - performed time break
2500 * @tty: device to break on
2501 * @duration: timeout in mS
2502 *
2503 * Perform a timed break on hardware that lacks its own driver level
2504 * timed break functionality.
2505 *
2506 * Locking:
Alan Cox28298232006-09-29 02:00:58 -07002507 * atomic_write_lock serializes
Alan Coxaf9b8972006-08-27 01:24:01 -07002508 *
Alan Coxaf9b8972006-08-27 01:24:01 -07002509 */
2510
Domen Puncerb20f3ae2005-06-25 14:58:42 -07002511static int send_break(struct tty_struct *tty, unsigned int duration)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002512{
Alan Cox9e98966c2008-07-22 11:18:03 +01002513 int retval;
2514
2515 if (tty->ops->break_ctl == NULL)
2516 return 0;
2517
2518 if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK)
2519 retval = tty->ops->break_ctl(tty, duration);
2520 else {
2521 /* Do the work ourselves */
2522 if (tty_write_lock(tty, 0) < 0)
2523 return -EINTR;
2524 retval = tty->ops->break_ctl(tty, -1);
2525 if (retval)
2526 goto out;
2527 if (!signal_pending(current))
2528 msleep_interruptible(duration);
2529 retval = tty->ops->break_ctl(tty, 0);
2530out:
2531 tty_write_unlock(tty);
2532 if (signal_pending(current))
2533 retval = -EINTR;
2534 }
2535 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536}
2537
Alan Coxaf9b8972006-08-27 01:24:01 -07002538/**
Alan Coxf34d7a52008-04-30 00:54:13 -07002539 * tty_tiocmget - get modem status
Alan Coxaf9b8972006-08-27 01:24:01 -07002540 * @tty: tty device
Alan Coxaf9b8972006-08-27 01:24:01 -07002541 * @p: pointer to result
2542 *
2543 * Obtain the modem status bits from the tty driver if the feature
Johan Hovold1b8b2082021-04-07 11:52:02 +02002544 * is supported. Return -ENOTTY if it is not available.
Alan Coxaf9b8972006-08-27 01:24:01 -07002545 *
2546 * Locking: none (up to the driver)
2547 */
2548
Alan Cox60b33c12011-02-14 16:26:14 +00002549static int tty_tiocmget(struct tty_struct *tty, int __user *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002550{
Johan Hovold1b8b2082021-04-07 11:52:02 +02002551 int retval = -ENOTTY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002552
Alan Coxf34d7a52008-04-30 00:54:13 -07002553 if (tty->ops->tiocmget) {
Alan Cox60b33c12011-02-14 16:26:14 +00002554 retval = tty->ops->tiocmget(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555
2556 if (retval >= 0)
2557 retval = put_user(retval, p);
2558 }
2559 return retval;
2560}
2561
Alan Coxaf9b8972006-08-27 01:24:01 -07002562/**
Alan Coxf34d7a52008-04-30 00:54:13 -07002563 * tty_tiocmset - set modem status
Alan Coxaf9b8972006-08-27 01:24:01 -07002564 * @tty: tty device
Alan Coxaf9b8972006-08-27 01:24:01 -07002565 * @cmd: command - clear bits, set bits or set all
2566 * @p: pointer to desired bits
2567 *
2568 * Set the modem status bits from the tty driver if the feature
Johan Hovold1b8b2082021-04-07 11:52:02 +02002569 * is supported. Return -ENOTTY if it is not available.
Alan Coxaf9b8972006-08-27 01:24:01 -07002570 *
2571 * Locking: none (up to the driver)
2572 */
2573
Alan Cox20b9d172011-02-14 16:26:50 +00002574static int tty_tiocmset(struct tty_struct *tty, unsigned int cmd,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002575 unsigned __user *p)
2576{
Alan Coxae677512008-07-16 21:56:54 +01002577 int retval;
2578 unsigned int set, clear, val;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002579
Alan Coxae677512008-07-16 21:56:54 +01002580 if (tty->ops->tiocmset == NULL)
Johan Hovold1b8b2082021-04-07 11:52:02 +02002581 return -ENOTTY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582
Alan Coxae677512008-07-16 21:56:54 +01002583 retval = get_user(val, p);
2584 if (retval)
2585 return retval;
2586 set = clear = 0;
2587 switch (cmd) {
2588 case TIOCMBIS:
2589 set = val;
2590 break;
2591 case TIOCMBIC:
2592 clear = val;
2593 break;
2594 case TIOCMSET:
2595 set = val;
2596 clear = ~val;
2597 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002598 }
Alan Coxae677512008-07-16 21:56:54 +01002599 set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
2600 clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
Alan Cox20b9d172011-02-14 16:26:50 +00002601 return tty->ops->tiocmset(tty, set, clear);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602}
2603
Uwe Kleine-Königd20c2192020-12-18 11:42:45 +01002604/**
2605 * tty_get_icount - get tty statistics
2606 * @tty: tty device
2607 * @icount: output parameter
2608 *
2609 * Gets a copy of the tty's icount statistics.
2610 *
2611 * Locking: none (up to the driver)
2612 */
2613int tty_get_icount(struct tty_struct *tty,
2614 struct serial_icounter_struct *icount)
2615{
2616 memset(icount, 0, sizeof(*icount));
2617
2618 if (tty->ops->get_icount)
2619 return tty->ops->get_icount(tty, icount);
2620 else
Johan Hovold1b8b2082021-04-07 11:52:02 +02002621 return -ENOTTY;
Uwe Kleine-Königd20c2192020-12-18 11:42:45 +01002622}
2623EXPORT_SYMBOL_GPL(tty_get_icount);
2624
Alan Coxd281da72010-09-16 18:21:24 +01002625static int tty_tiocgicount(struct tty_struct *tty, void __user *arg)
2626{
Alan Coxd281da72010-09-16 18:21:24 +01002627 struct serial_icounter_struct icount;
Uwe Kleine-Königd20c2192020-12-18 11:42:45 +01002628 int retval;
2629
2630 retval = tty_get_icount(tty, &icount);
Alan Coxd281da72010-09-16 18:21:24 +01002631 if (retval != 0)
2632 return retval;
Uwe Kleine-Königd20c2192020-12-18 11:42:45 +01002633
Alan Coxd281da72010-09-16 18:21:24 +01002634 if (copy_to_user(arg, &icount, sizeof(icount)))
2635 return -EFAULT;
2636 return 0;
2637}
2638
Johan Hovold885c77d2021-04-07 11:52:05 +02002639static int tty_set_serial(struct tty_struct *tty, struct serial_struct *ss)
Jiri Slaby8a8ae622014-11-06 16:56:33 +01002640{
Jiri Slaby8a8ae622014-11-06 16:56:33 +01002641 char comm[TASK_COMM_LEN];
2642 int flags;
2643
Johan Hovold885c77d2021-04-07 11:52:05 +02002644 flags = ss->flags & ASYNC_DEPRECATED;
Jiri Slaby8a8ae622014-11-06 16:56:33 +01002645
Johan Hovold1b7bc6b2021-04-07 11:52:04 +02002646 if (flags)
2647 pr_warn_ratelimited("%s: '%s' is using deprecated serial flags (with no effect): %.8x\n",
2648 __func__, get_task_comm(comm, current), flags);
Johan Hovold885c77d2021-04-07 11:52:05 +02002649
Al Viro2f46a2c2018-09-11 21:53:32 -04002650 if (!tty->ops->set_serial)
Al Viro930236a2018-09-12 07:46:51 -04002651 return -ENOTTY;
Johan Hovold885c77d2021-04-07 11:52:05 +02002652
2653 return tty->ops->set_serial(tty, ss);
2654}
2655
2656static int tty_tiocsserial(struct tty_struct *tty, struct serial_struct __user *ss)
2657{
2658 struct serial_struct v;
2659
2660 if (copy_from_user(&v, ss, sizeof(*ss)))
2661 return -EFAULT;
2662
2663 return tty_set_serial(tty, &v);
Al Viro2f46a2c2018-09-11 21:53:32 -04002664}
2665
2666static int tty_tiocgserial(struct tty_struct *tty, struct serial_struct __user *ss)
2667{
2668 struct serial_struct v;
2669 int err;
2670
Gustavo A. R. Silvaa3241892020-07-23 17:34:22 -05002671 memset(&v, 0, sizeof(v));
Al Viro2f46a2c2018-09-11 21:53:32 -04002672 if (!tty->ops->get_serial)
Al Viro930236a2018-09-12 07:46:51 -04002673 return -ENOTTY;
Al Viro2f46a2c2018-09-11 21:53:32 -04002674 err = tty->ops->get_serial(tty, &v);
Gustavo A. R. Silvaa3241892020-07-23 17:34:22 -05002675 if (!err && copy_to_user(ss, &v, sizeof(v)))
Al Viro2f46a2c2018-09-11 21:53:32 -04002676 err = -EFAULT;
2677 return err;
Jiri Slaby8a8ae622014-11-06 16:56:33 +01002678}
2679
Peter Hurley8f166e02014-10-16 14:59:41 -04002680/*
2681 * if pty, return the slave side (real_tty)
2682 * otherwise, return self
2683 */
2684static struct tty_struct *tty_pair_get_tty(struct tty_struct *tty)
Alan Coxe8b70e72009-06-11 12:48:02 +01002685{
2686 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
2687 tty->driver->subtype == PTY_TYPE_MASTER)
2688 tty = tty->link;
2689 return tty;
2690}
Alan Coxe8b70e72009-06-11 12:48:02 +01002691
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692/*
2693 * Split this up, as gcc can choke on it otherwise..
2694 */
Alan Cox04f378b2008-04-30 00:53:29 -07002695long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696{
Nick Piggind996b622010-08-18 04:37:36 +10002697 struct tty_struct *tty = file_tty(file);
2698 struct tty_struct *real_tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699 void __user *p = (void __user *)arg;
2700 int retval;
2701 struct tty_ldisc *ld;
Alan Cox37bdfb02008-02-08 04:18:47 -08002702
Al Viro6131ffa2013-02-27 16:59:05 -05002703 if (tty_paranoia_check(tty, file_inode(file), "tty_ioctl"))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704 return -EINVAL;
2705
Alan Coxe8b70e72009-06-11 12:48:02 +01002706 real_tty = tty_pair_get_tty(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002707
2708 /*
2709 * Factor out some common prep work
2710 */
2711 switch (cmd) {
2712 case TIOCSETD:
2713 case TIOCSBRK:
2714 case TIOCCBRK:
2715 case TCSBRK:
Alan Cox37bdfb02008-02-08 04:18:47 -08002716 case TCSBRKP:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002717 retval = tty_check_change(tty);
2718 if (retval)
2719 return retval;
2720 if (cmd != TIOCCBRK) {
2721 tty_wait_until_sent(tty, 0);
2722 if (signal_pending(current))
2723 return -EINTR;
2724 }
2725 break;
2726 }
2727
Alan Cox9e98966c2008-07-22 11:18:03 +01002728 /*
2729 * Now do the stuff.
2730 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002731 switch (cmd) {
Alan Cox37bdfb02008-02-08 04:18:47 -08002732 case TIOCSTI:
2733 return tiocsti(tty, p);
2734 case TIOCGWINSZ:
Alan Cox8f520022008-10-13 10:38:46 +01002735 return tiocgwinsz(real_tty, p);
Alan Cox37bdfb02008-02-08 04:18:47 -08002736 case TIOCSWINSZ:
Alan Coxfc6f6232009-01-02 13:43:17 +00002737 return tiocswinsz(real_tty, p);
Alan Cox37bdfb02008-02-08 04:18:47 -08002738 case TIOCCONS:
2739 return real_tty != tty ? -EINVAL : tioccons(file);
Alan Cox37bdfb02008-02-08 04:18:47 -08002740 case TIOCEXCL:
2741 set_bit(TTY_EXCLUSIVE, &tty->flags);
2742 return 0;
2743 case TIOCNXCL:
2744 clear_bit(TTY_EXCLUSIVE, &tty->flags);
2745 return 0;
Cyrill Gorcunov84fd7bd2012-10-24 23:43:22 +04002746 case TIOCGEXCL:
2747 {
2748 int excl = test_bit(TTY_EXCLUSIVE, &tty->flags);
Xiaofei Tane73b2402021-05-12 17:26:15 +08002749
Cyrill Gorcunov84fd7bd2012-10-24 23:43:22 +04002750 return put_user(excl, (int __user *)p);
2751 }
Alan Cox37bdfb02008-02-08 04:18:47 -08002752 case TIOCGETD:
Peter Hurley5c17c862016-01-10 22:40:55 -08002753 return tiocgetd(tty, p);
Alan Cox37bdfb02008-02-08 04:18:47 -08002754 case TIOCSETD:
2755 return tiocsetd(tty, p);
Kay Sievers3c95c982011-02-17 18:39:28 +01002756 case TIOCVHANGUP:
2757 if (!capable(CAP_SYS_ADMIN))
2758 return -EPERM;
2759 tty_vhangup(tty);
2760 return 0;
Werner Finkb7b8de02010-12-03 12:48:23 +01002761 case TIOCGDEV:
2762 {
2763 unsigned int ret = new_encode_dev(tty_devnum(real_tty));
Xiaofei Tane73b2402021-05-12 17:26:15 +08002764
Werner Finkb7b8de02010-12-03 12:48:23 +01002765 return put_user(ret, (unsigned int __user *)p);
2766 }
Alan Cox37bdfb02008-02-08 04:18:47 -08002767 /*
2768 * Break handling
2769 */
2770 case TIOCSBRK: /* Turn break on, unconditionally */
Alan Coxf34d7a52008-04-30 00:54:13 -07002771 if (tty->ops->break_ctl)
Alan Cox9e98966c2008-07-22 11:18:03 +01002772 return tty->ops->break_ctl(tty, -1);
Alan Cox37bdfb02008-02-08 04:18:47 -08002773 return 0;
Alan Cox37bdfb02008-02-08 04:18:47 -08002774 case TIOCCBRK: /* Turn break off, unconditionally */
Alan Coxf34d7a52008-04-30 00:54:13 -07002775 if (tty->ops->break_ctl)
Alan Cox9e98966c2008-07-22 11:18:03 +01002776 return tty->ops->break_ctl(tty, 0);
Alan Cox37bdfb02008-02-08 04:18:47 -08002777 return 0;
2778 case TCSBRK: /* SVID version: non-zero arg --> no break */
2779 /* non-zero arg means wait for all output data
2780 * to be sent (performed above) but don't send break.
2781 * This is used by the tcdrain() termios function.
Linus Torvalds1da177e2005-04-16 15:20:36 -07002782 */
Alan Cox37bdfb02008-02-08 04:18:47 -08002783 if (!arg)
2784 return send_break(tty, 250);
2785 return 0;
2786 case TCSBRKP: /* support for POSIX tcsendbreak() */
2787 return send_break(tty, arg ? arg*100 : 250);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002788
Alan Cox37bdfb02008-02-08 04:18:47 -08002789 case TIOCMGET:
Alan Cox60b33c12011-02-14 16:26:14 +00002790 return tty_tiocmget(tty, p);
Alan Cox37bdfb02008-02-08 04:18:47 -08002791 case TIOCMSET:
2792 case TIOCMBIC:
2793 case TIOCMBIS:
Alan Cox20b9d172011-02-14 16:26:50 +00002794 return tty_tiocmset(tty, cmd, p);
Alan Coxd281da72010-09-16 18:21:24 +01002795 case TIOCGICOUNT:
Al Viroa3096192018-09-12 18:37:18 -04002796 return tty_tiocgicount(tty, p);
Alan Cox37bdfb02008-02-08 04:18:47 -08002797 case TCFLSH:
2798 switch (arg) {
2799 case TCIFLUSH:
2800 case TCIOFLUSH:
2801 /* flush tty buffer and allow ldisc to process ioctl */
Peter Hurley86c80a82014-11-05 12:13:09 -05002802 tty_buffer_flush(tty, NULL);
Paul Fulghumc5c34d42007-05-12 10:36:55 -07002803 break;
Alan Cox37bdfb02008-02-08 04:18:47 -08002804 }
2805 break;
Jiri Slaby8a8ae622014-11-06 16:56:33 +01002806 case TIOCSSERIAL:
Al Viro930236a2018-09-12 07:46:51 -04002807 return tty_tiocsserial(tty, p);
Al Viro2f46a2c2018-09-11 21:53:32 -04002808 case TIOCGSERIAL:
Al Viro930236a2018-09-12 07:46:51 -04002809 return tty_tiocgserial(tty, p);
Eric W. Biederman311fc652017-08-24 15:13:29 -05002810 case TIOCGPTPEER:
2811 /* Special because the struct file is needed */
2812 return ptm_open_peer(file, tty, (int)arg);
Nicolas Pitrea1235b32017-04-12 18:37:16 -04002813 default:
2814 retval = tty_jobctrl_ioctl(tty, real_tty, file, cmd, arg);
2815 if (retval != -ENOIOCTLCMD)
2816 return retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 }
Alan Coxf34d7a52008-04-30 00:54:13 -07002818 if (tty->ops->ioctl) {
Peter Hurleyc961bfb2014-11-05 12:26:25 -05002819 retval = tty->ops->ioctl(tty, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820 if (retval != -ENOIOCTLCMD)
2821 return retval;
2822 }
2823 ld = tty_ldisc_ref_wait(tty);
Peter Hurleye55afd12016-01-10 22:41:01 -08002824 if (!ld)
2825 return hung_up_tty_ioctl(file, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 retval = -EINVAL;
Alan Coxa352def2008-07-16 21:53:12 +01002827 if (ld->ops->ioctl) {
2828 retval = ld->ops->ioctl(tty, file, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829 if (retval == -ENOIOCTLCMD)
Wanlong Gaobbb63c52012-08-27 15:23:12 +08002830 retval = -ENOTTY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002831 }
2832 tty_ldisc_deref(ld);
2833 return retval;
2834}
2835
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002836#ifdef CONFIG_COMPAT
Al Viro77654352018-09-12 11:28:34 -04002837
2838struct serial_struct32 {
Gustavo A. R. Silva52b52e92020-07-23 17:32:25 -05002839 compat_int_t type;
2840 compat_int_t line;
2841 compat_uint_t port;
2842 compat_int_t irq;
2843 compat_int_t flags;
2844 compat_int_t xmit_fifo_size;
2845 compat_int_t custom_divisor;
2846 compat_int_t baud_base;
2847 unsigned short close_delay;
2848 char io_type;
2849 char reserved_char;
2850 compat_int_t hub6;
2851 unsigned short closing_wait; /* time to wait before closing */
2852 unsigned short closing_wait2; /* no longer used... */
2853 compat_uint_t iomem_base;
2854 unsigned short iomem_reg_shift;
2855 unsigned int port_high;
2856 /* compat_ulong_t iomap_base FIXME */
2857 compat_int_t reserved;
Al Viro77654352018-09-12 11:28:34 -04002858};
2859
2860static int compat_tty_tiocsserial(struct tty_struct *tty,
2861 struct serial_struct32 __user *ss)
2862{
Al Viro77654352018-09-12 11:28:34 -04002863 struct serial_struct32 v32;
2864 struct serial_struct v;
Al Viro77654352018-09-12 11:28:34 -04002865
Gustavo A. R. Silvaa3241892020-07-23 17:34:22 -05002866 if (copy_from_user(&v32, ss, sizeof(*ss)))
Al Viro77654352018-09-12 11:28:34 -04002867 return -EFAULT;
2868
2869 memcpy(&v, &v32, offsetof(struct serial_struct32, iomem_base));
2870 v.iomem_base = compat_ptr(v32.iomem_base);
2871 v.iomem_reg_shift = v32.iomem_reg_shift;
2872 v.port_high = v32.port_high;
2873 v.iomap_base = 0;
2874
Johan Hovold885c77d2021-04-07 11:52:05 +02002875 return tty_set_serial(tty, &v);
Al Viro77654352018-09-12 11:28:34 -04002876}
2877
2878static int compat_tty_tiocgserial(struct tty_struct *tty,
2879 struct serial_struct32 __user *ss)
2880{
2881 struct serial_struct32 v32;
2882 struct serial_struct v;
2883 int err;
Eric Biggers17329562020-02-24 10:20:43 -08002884
2885 memset(&v, 0, sizeof(v));
2886 memset(&v32, 0, sizeof(v32));
Al Viro77654352018-09-12 11:28:34 -04002887
Eric Biggers6e622cd2020-02-24 10:20:44 -08002888 if (!tty->ops->get_serial)
Al Viro77654352018-09-12 11:28:34 -04002889 return -ENOTTY;
2890 err = tty->ops->get_serial(tty, &v);
2891 if (!err) {
2892 memcpy(&v32, &v, offsetof(struct serial_struct32, iomem_base));
2893 v32.iomem_base = (unsigned long)v.iomem_base >> 32 ?
2894 0xfffffff : ptr_to_compat(v.iomem_base);
2895 v32.iomem_reg_shift = v.iomem_reg_shift;
2896 v32.port_high = v.port_high;
Gustavo A. R. Silvaa3241892020-07-23 17:34:22 -05002897 if (copy_to_user(ss, &v32, sizeof(v32)))
Al Viro77654352018-09-12 11:28:34 -04002898 err = -EFAULT;
2899 }
2900 return err;
2901}
Alan Cox37bdfb02008-02-08 04:18:47 -08002902static long tty_compat_ioctl(struct file *file, unsigned int cmd,
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002903 unsigned long arg)
2904{
Nick Piggind996b622010-08-18 04:37:36 +10002905 struct tty_struct *tty = file_tty(file);
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002906 struct tty_ldisc *ld;
2907 int retval = -ENOIOCTLCMD;
2908
Al Viroe2112032018-09-11 19:47:09 -04002909 switch (cmd) {
Arnd Bergmannc7dc5042019-06-03 23:07:12 +02002910 case TIOCOUTQ:
Al Viroe2112032018-09-11 19:47:09 -04002911 case TIOCSTI:
2912 case TIOCGWINSZ:
2913 case TIOCSWINSZ:
2914 case TIOCGEXCL:
2915 case TIOCGETD:
2916 case TIOCSETD:
2917 case TIOCGDEV:
2918 case TIOCMGET:
2919 case TIOCMSET:
2920 case TIOCMBIC:
2921 case TIOCMBIS:
2922 case TIOCGICOUNT:
2923 case TIOCGPGRP:
2924 case TIOCSPGRP:
2925 case TIOCGSID:
2926 case TIOCSERGETLSR:
2927 case TIOCGRS485:
2928 case TIOCSRS485:
2929#ifdef TIOCGETP
2930 case TIOCGETP:
2931 case TIOCSETP:
2932 case TIOCSETN:
2933#endif
2934#ifdef TIOCGETC
2935 case TIOCGETC:
2936 case TIOCSETC:
2937#endif
2938#ifdef TIOCGLTC
2939 case TIOCGLTC:
2940 case TIOCSLTC:
2941#endif
2942 case TCSETSF:
2943 case TCSETSW:
2944 case TCSETS:
2945 case TCGETS:
2946#ifdef TCGETS2
2947 case TCGETS2:
2948 case TCSETSF2:
2949 case TCSETSW2:
2950 case TCSETS2:
2951#endif
2952 case TCGETA:
2953 case TCSETAF:
2954 case TCSETAW:
2955 case TCSETA:
2956 case TIOCGLCKTRMIOS:
2957 case TIOCSLCKTRMIOS:
2958#ifdef TCGETX
2959 case TCGETX:
2960 case TCSETX:
2961 case TCSETXW:
2962 case TCSETXF:
2963#endif
2964 case TIOCGSOFTCAR:
2965 case TIOCSSOFTCAR:
Arnd Bergmannb7aff092019-06-06 10:07:36 +02002966
2967 case PPPIOCGCHAN:
2968 case PPPIOCGUNIT:
Al Viroe2112032018-09-11 19:47:09 -04002969 return tty_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
2970 case TIOCCONS:
2971 case TIOCEXCL:
2972 case TIOCNXCL:
2973 case TIOCVHANGUP:
2974 case TIOCSBRK:
2975 case TIOCCBRK:
2976 case TCSBRK:
2977 case TCSBRKP:
2978 case TCFLSH:
2979 case TIOCGPTPEER:
2980 case TIOCNOTTY:
2981 case TIOCSCTTY:
2982 case TCXONC:
2983 case TIOCMIWAIT:
2984 case TIOCSERCONFIG:
2985 return tty_ioctl(file, cmd, arg);
2986 }
2987
Al Viro6131ffa2013-02-27 16:59:05 -05002988 if (tty_paranoia_check(tty, file_inode(file), "tty_ioctl"))
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002989 return -EINVAL;
2990
Al Viro77654352018-09-12 11:28:34 -04002991 switch (cmd) {
2992 case TIOCSSERIAL:
2993 return compat_tty_tiocsserial(tty, compat_ptr(arg));
2994 case TIOCGSERIAL:
2995 return compat_tty_tiocgserial(tty, compat_ptr(arg));
2996 }
Alan Coxf34d7a52008-04-30 00:54:13 -07002997 if (tty->ops->compat_ioctl) {
Peter Hurleyc961bfb2014-11-05 12:26:25 -05002998 retval = tty->ops->compat_ioctl(tty, cmd, arg);
Paul Fulghume10cc1d2007-05-10 22:22:50 -07002999 if (retval != -ENOIOCTLCMD)
3000 return retval;
3001 }
3002
3003 ld = tty_ldisc_ref_wait(tty);
Peter Hurleye55afd12016-01-10 22:41:01 -08003004 if (!ld)
3005 return hung_up_tty_compat_ioctl(file, cmd, arg);
Alan Coxa352def2008-07-16 21:53:12 +01003006 if (ld->ops->compat_ioctl)
3007 retval = ld->ops->compat_ioctl(tty, file, cmd, arg);
Al Virof0193d32018-09-13 22:12:15 -04003008 if (retval == -ENOIOCTLCMD && ld->ops->ioctl)
3009 retval = ld->ops->ioctl(tty, file,
3010 (unsigned long)compat_ptr(cmd), arg);
Paul Fulghume10cc1d2007-05-10 22:22:50 -07003011 tty_ldisc_deref(ld);
3012
3013 return retval;
3014}
3015#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003016
Al Viroc3c073f2012-08-21 22:32:06 -04003017static int this_tty(const void *t, struct file *file, unsigned fd)
3018{
Linus Torvaldsdd78b0c2021-01-19 10:49:19 -08003019 if (likely(file->f_op->read_iter != tty_read))
Al Viroc3c073f2012-08-21 22:32:06 -04003020 return 0;
3021 return file_tty(file) != t ? 0 : fd + 1;
3022}
Xiaofei Tand91c1a32021-05-12 17:26:17 +08003023
Linus Torvalds1da177e2005-04-16 15:20:36 -07003024/*
3025 * This implements the "Secure Attention Key" --- the idea is to
3026 * prevent trojan horses by killing all processes associated with this
3027 * tty when the user hits the "Secure Attention Key". Required for
3028 * super-paranoid applications --- see the Orange Book for more details.
Alan Cox37bdfb02008-02-08 04:18:47 -08003029 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07003030 * This code could be nicer; ideally it should send a HUP, wait a few
3031 * seconds, then send a INT, and then a KILL signal. But you then
3032 * have to coordinate with the init process, since all processes associated
3033 * with the current tty must be dead before the new getty is allowed
3034 * to spawn.
3035 *
3036 * Now, if it would be correct ;-/ The current code has a nasty hole -
3037 * it doesn't catch files in flight. We may send the descriptor to ourselves
3038 * via AF_UNIX socket, close it and later fetch from socket. FIXME.
3039 *
3040 * Nasty bug: do_SAK is being called in interrupt context. This can
3041 * deadlock. We punt it up to process context. AKPM - 16Mar2001
3042 */
Eric W. Biederman8b6312f2007-02-10 01:44:34 -08003043void __do_SAK(struct tty_struct *tty)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003044{
3045#ifdef TTY_SOFT_SAK
3046 tty_hangup(tty);
3047#else
Eric W. Biederman652486f2006-03-28 16:11:02 -08003048 struct task_struct *g, *p;
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08003049 struct pid *session;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003050 int i;
Jann Hornc8bcd9c2020-12-03 02:25:05 +01003051 unsigned long flags;
Alan Cox37bdfb02008-02-08 04:18:47 -08003052
Linus Torvalds1da177e2005-04-16 15:20:36 -07003053 if (!tty)
3054 return;
Jann Hornc8bcd9c2020-12-03 02:25:05 +01003055
Jiri Slaby64d608d2021-05-05 11:19:06 +02003056 spin_lock_irqsave(&tty->ctrl.lock, flags);
3057 session = get_pid(tty->ctrl.session);
3058 spin_unlock_irqrestore(&tty->ctrl.lock, flags);
Alan Cox37bdfb02008-02-08 04:18:47 -08003059
Dan Carpenterb3f13de2006-12-13 00:35:09 -08003060 tty_ldisc_flush(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003061
Alan Coxf34d7a52008-04-30 00:54:13 -07003062 tty_driver_flush_buffer(tty);
Alan Cox37bdfb02008-02-08 04:18:47 -08003063
Linus Torvalds1da177e2005-04-16 15:20:36 -07003064 read_lock(&tasklist_lock);
Eric W. Biederman652486f2006-03-28 16:11:02 -08003065 /* Kill the entire session */
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08003066 do_each_pid_task(session, PIDTYPE_SID, p) {
Peter Hurley9b42bb72015-11-08 13:01:14 -05003067 tty_notice(tty, "SAK: killed process %d (%s): by session\n",
3068 task_pid_nr(p), p->comm);
Eric W. Biedermana8ebd172018-07-20 15:59:17 -05003069 group_send_sig_info(SIGKILL, SEND_SIG_PRIV, p, PIDTYPE_SID);
Eric W. Biedermanab521dc2007-02-12 00:53:00 -08003070 } while_each_pid_task(session, PIDTYPE_SID, p);
Peter Hurley9b42bb72015-11-08 13:01:14 -05003071
3072 /* Now kill any processes that happen to have the tty open */
Eric W. Biederman652486f2006-03-28 16:11:02 -08003073 do_each_thread(g, p) {
3074 if (p->signal->tty == tty) {
Peter Hurley9b42bb72015-11-08 13:01:14 -05003075 tty_notice(tty, "SAK: killed process %d (%s): by controlling tty\n",
3076 task_pid_nr(p), p->comm);
Eric W. Biedermana8ebd172018-07-20 15:59:17 -05003077 group_send_sig_info(SIGKILL, SEND_SIG_PRIV, p, PIDTYPE_SID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003078 continue;
3079 }
3080 task_lock(p);
Al Viroc3c073f2012-08-21 22:32:06 -04003081 i = iterate_fd(p->files, 0, this_tty, tty);
3082 if (i != 0) {
Peter Hurley9b42bb72015-11-08 13:01:14 -05003083 tty_notice(tty, "SAK: killed process %d (%s): by fd#%d\n",
3084 task_pid_nr(p), p->comm, i - 1);
Eric W. Biedermana8ebd172018-07-20 15:59:17 -05003085 group_send_sig_info(SIGKILL, SEND_SIG_PRIV, p, PIDTYPE_SID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003086 }
3087 task_unlock(p);
Eric W. Biederman652486f2006-03-28 16:11:02 -08003088 } while_each_thread(g, p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003089 read_unlock(&tasklist_lock);
Jann Hornc8bcd9c2020-12-03 02:25:05 +01003090 put_pid(session);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003091#endif
3092}
3093
Eric W. Biederman8b6312f2007-02-10 01:44:34 -08003094static void do_SAK_work(struct work_struct *work)
3095{
3096 struct tty_struct *tty =
3097 container_of(work, struct tty_struct, SAK_work);
3098 __do_SAK(tty);
3099}
3100
Linus Torvalds1da177e2005-04-16 15:20:36 -07003101/*
3102 * The tq handling here is a little racy - tty->SAK_work may already be queued.
3103 * Fortunately we don't need to worry, because if ->SAK_work is already queued,
3104 * the values which we write to it will be identical to the values which it
3105 * already has. --akpm
3106 */
3107void do_SAK(struct tty_struct *tty)
3108{
3109 if (!tty)
3110 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111 schedule_work(&tty->SAK_work);
3112}
3113
3114EXPORT_SYMBOL(do_SAK);
3115
Dmitry Eremin-Solenikov30004ac2010-08-09 18:22:49 +04003116/* Must put_device() after it's unused! */
3117static struct device *tty_get_device(struct tty_struct *tty)
3118{
3119 dev_t devt = tty_devnum(tty);
Xiaofei Tane73b2402021-05-12 17:26:15 +08003120
Suzuki K Poulose4495dfd2019-07-23 23:18:35 +01003121 return class_find_device_by_devt(tty_class, devt);
Dmitry Eremin-Solenikov30004ac2010-08-09 18:22:49 +04003122}
3123
3124
Lee Jones08aa5042020-11-04 19:35:25 +00003125/*
Rasmus Villemoes2c964a22014-07-10 21:01:22 +02003126 * alloc_tty_struct
Alan Coxaf9b8972006-08-27 01:24:01 -07003127 *
Rasmus Villemoes2c964a22014-07-10 21:01:22 +02003128 * This subroutine allocates and initializes a tty structure.
Alan Coxaf9b8972006-08-27 01:24:01 -07003129 *
Rasmus Villemoes2c964a22014-07-10 21:01:22 +02003130 * Locking: none - tty in question is not exposed at this point
Linus Torvalds1da177e2005-04-16 15:20:36 -07003131 */
Alan Coxaf9b8972006-08-27 01:24:01 -07003132
Rasmus Villemoes2c964a22014-07-10 21:01:22 +02003133struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134{
Rasmus Villemoes2c964a22014-07-10 21:01:22 +02003135 struct tty_struct *tty;
3136
3137 tty = kzalloc(sizeof(*tty), GFP_KERNEL);
3138 if (!tty)
3139 return NULL;
3140
Alan Cox9c9f4de2008-10-13 10:37:26 +01003141 kref_init(&tty->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003142 tty->magic = TTY_MAGIC;
Tetsuo Handa903f9db2018-04-05 19:40:16 +09003143 if (tty_ldisc_init(tty)) {
3144 kfree(tty);
3145 return NULL;
3146 }
Jiri Slaby64d608d2021-05-05 11:19:06 +02003147 tty->ctrl.session = NULL;
3148 tty->ctrl.pgrp = NULL;
Alan Cox89c8d912012-08-08 16:30:13 +01003149 mutex_init(&tty->legacy_mutex);
Peter Hurleyd8c1f922013-06-15 09:14:31 -04003150 mutex_init(&tty->throttle_mutex);
Peter Hurley6a1c0682013-06-15 09:14:23 -04003151 init_rwsem(&tty->termios_rwsem);
Peter Hurleydee4a0b2013-07-24 16:43:51 -04003152 mutex_init(&tty->winsize_mutex);
Peter Hurley36697522013-06-15 07:04:48 -04003153 init_ldsem(&tty->ldisc_sem);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003154 init_waitqueue_head(&tty->write_wait);
3155 init_waitqueue_head(&tty->read_wait);
David Howells65f27f32006-11-22 14:55:48 +00003156 INIT_WORK(&tty->hangup_work, do_tty_hangup);
Ingo Molnar70522e12006-03-23 03:00:31 -08003157 mutex_init(&tty->atomic_write_lock);
Jiri Slaby64d608d2021-05-05 11:19:06 +02003158 spin_lock_init(&tty->ctrl.lock);
Jiri Slaby6e94dbc2021-05-05 11:19:05 +02003159 spin_lock_init(&tty->flow.lock);
Peter Hurley4a510962016-01-09 21:35:23 -08003160 spin_lock_init(&tty->files_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003161 INIT_LIST_HEAD(&tty->tty_files);
Eric W. Biederman7f1f86a2007-02-13 14:38:58 -07003162 INIT_WORK(&tty->SAK_work, do_SAK_work);
Alan Coxbf970ee2008-10-13 10:42:39 +01003163
3164 tty->driver = driver;
3165 tty->ops = driver->ops;
3166 tty->index = idx;
3167 tty_line_name(driver, idx, tty->name);
Dmitry Eremin-Solenikov30004ac2010-08-09 18:22:49 +04003168 tty->dev = tty_get_device(tty);
Rasmus Villemoes2c964a22014-07-10 21:01:22 +02003169
3170 return tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003171}
3172
Alan Coxf34d7a52008-04-30 00:54:13 -07003173/**
3174 * tty_put_char - write one character to a tty
3175 * @tty: tty
3176 * @ch: character
3177 *
3178 * Write one byte to the tty using the provided put_char method
3179 * if present. Returns the number of characters successfully output.
3180 *
3181 * Note: the specific put_char operation in the driver layer may go
3182 * away soon. Don't call it directly, use this method
Linus Torvalds1da177e2005-04-16 15:20:36 -07003183 */
Alan Coxaf9b8972006-08-27 01:24:01 -07003184
Alan Coxf34d7a52008-04-30 00:54:13 -07003185int tty_put_char(struct tty_struct *tty, unsigned char ch)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186{
Alan Coxf34d7a52008-04-30 00:54:13 -07003187 if (tty->ops->put_char)
3188 return tty->ops->put_char(tty, ch);
3189 return tty->ops->write(tty, &ch, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003190}
Alan Coxf34d7a52008-04-30 00:54:13 -07003191EXPORT_SYMBOL_GPL(tty_put_char);
3192
Alan Coxd81ed102008-10-13 10:41:42 +01003193struct class *tty_class;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194
Jiri Slaby7e73eca2012-08-08 22:26:44 +02003195static int tty_cdev_add(struct tty_driver *driver, dev_t dev,
3196 unsigned int index, unsigned int count)
3197{
Leon Yuc1a752b2015-09-07 13:08:37 +00003198 int err;
3199
Jiri Slaby7e73eca2012-08-08 22:26:44 +02003200 /* init here, since reused cdevs cause crashes */
Richard Wattsa3a10ce2015-05-19 16:06:53 +01003201 driver->cdevs[index] = cdev_alloc();
3202 if (!driver->cdevs[index])
3203 return -ENOMEM;
Leon Yuc1a752b2015-09-07 13:08:37 +00003204 driver->cdevs[index]->ops = &tty_fops;
Richard Wattsa3a10ce2015-05-19 16:06:53 +01003205 driver->cdevs[index]->owner = driver->owner;
Leon Yuc1a752b2015-09-07 13:08:37 +00003206 err = cdev_add(driver->cdevs[index], dev, count);
3207 if (err)
3208 kobject_put(&driver->cdevs[index]->kobj);
3209 return err;
Jiri Slaby7e73eca2012-08-08 22:26:44 +02003210}
3211
Linus Torvalds1da177e2005-04-16 15:20:36 -07003212/**
Alan Coxaf9b8972006-08-27 01:24:01 -07003213 * tty_register_device - register a tty device
3214 * @driver: the tty driver that describes the tty device
3215 * @index: the index in the tty driver for this tty device
3216 * @device: a struct device that is associated with this tty device.
3217 * This field is optional, if there is no known struct device
3218 * for this tty device it can be set to NULL safely.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003219 *
Greg Kroah-Hartman01107d32006-08-07 22:19:37 -07003220 * Returns a pointer to the struct device for this tty device
3221 * (or ERR_PTR(-EFOO) on error).
Hansjoerg Lipp1cdcb6b2006-04-22 18:36:53 +02003222 *
Alan Coxaf9b8972006-08-27 01:24:01 -07003223 * This call is required to be made to register an individual tty device
3224 * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If
3225 * that bit is not set, this function should not be called by a tty
3226 * driver.
3227 *
3228 * Locking: ??
Linus Torvalds1da177e2005-04-16 15:20:36 -07003229 */
Alan Coxaf9b8972006-08-27 01:24:01 -07003230
Greg Kroah-Hartman01107d32006-08-07 22:19:37 -07003231struct device *tty_register_device(struct tty_driver *driver, unsigned index,
3232 struct device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003233{
Tomas Hlavacek6915c0e2012-09-06 03:17:18 +02003234 return tty_register_device_attr(driver, index, device, NULL, NULL);
3235}
3236EXPORT_SYMBOL(tty_register_device);
3237
Tomas Hlavacekb1b79912012-09-06 23:17:47 +02003238static void tty_device_create_release(struct device *dev)
3239{
Peter Hurley83db1df2015-11-08 13:01:21 -05003240 dev_dbg(dev, "releasing...\n");
Tomas Hlavacekb1b79912012-09-06 23:17:47 +02003241 kfree(dev);
3242}
3243
Tomas Hlavacek6915c0e2012-09-06 03:17:18 +02003244/**
3245 * tty_register_device_attr - register a tty device
3246 * @driver: the tty driver that describes the tty device
3247 * @index: the index in the tty driver for this tty device
3248 * @device: a struct device that is associated with this tty device.
3249 * This field is optional, if there is no known struct device
3250 * for this tty device it can be set to NULL safely.
3251 * @drvdata: Driver data to be set to device.
3252 * @attr_grp: Attribute group to be set on device.
3253 *
3254 * Returns a pointer to the struct device for this tty device
3255 * (or ERR_PTR(-EFOO) on error).
3256 *
3257 * This call is required to be made to register an individual tty device
3258 * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If
3259 * that bit is not set, this function should not be called by a tty
3260 * driver.
3261 *
3262 * Locking: ??
3263 */
3264struct device *tty_register_device_attr(struct tty_driver *driver,
3265 unsigned index, struct device *device,
3266 void *drvdata,
3267 const struct attribute_group **attr_grp)
3268{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003269 char name[64];
Tomas Hlavacek6915c0e2012-09-06 03:17:18 +02003270 dev_t devt = MKDEV(driver->major, driver->minor_start) + index;
Johan Hovold93857ed2017-03-30 15:39:36 +02003271 struct ktermios *tp;
Johan Hovold6a7e6f72017-03-30 15:39:34 +02003272 struct device *dev;
3273 int retval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003274
3275 if (index >= driver->num) {
Peter Hurley656fb862015-11-08 13:01:15 -05003276 pr_err("%s: Attempt to register invalid tty line number (%d)\n",
3277 driver->name, index);
Hansjoerg Lipp1cdcb6b2006-04-22 18:36:53 +02003278 return ERR_PTR(-EINVAL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003279 }
3280
Linus Torvalds1da177e2005-04-16 15:20:36 -07003281 if (driver->type == TTY_DRIVER_TYPE_PTY)
3282 pty_line_name(driver, index, name);
3283 else
3284 tty_line_name(driver, index, name);
Hansjoerg Lipp1cdcb6b2006-04-22 18:36:53 +02003285
Tomas Hlavacek6915c0e2012-09-06 03:17:18 +02003286 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
Johan Hovold6a7e6f72017-03-30 15:39:34 +02003287 if (!dev)
3288 return ERR_PTR(-ENOMEM);
Jiri Slaby7e73eca2012-08-08 22:26:44 +02003289
Tomas Hlavacek6915c0e2012-09-06 03:17:18 +02003290 dev->devt = devt;
3291 dev->class = tty_class;
3292 dev->parent = device;
Tomas Hlavacekb1b79912012-09-06 23:17:47 +02003293 dev->release = tty_device_create_release;
Tomas Hlavacek6915c0e2012-09-06 03:17:18 +02003294 dev_set_name(dev, "%s", name);
3295 dev->groups = attr_grp;
3296 dev_set_drvdata(dev, drvdata);
3297
Johan Hovold6a7e6f72017-03-30 15:39:34 +02003298 dev_set_uevent_suppress(dev, 1);
3299
Tomas Hlavacek6915c0e2012-09-06 03:17:18 +02003300 retval = device_register(dev);
3301 if (retval)
Johan Hovold6a7e6f72017-03-30 15:39:34 +02003302 goto err_put;
3303
3304 if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) {
Johan Hovold93857ed2017-03-30 15:39:36 +02003305 /*
3306 * Free any saved termios data so that the termios state is
3307 * reset when reusing a minor number.
3308 */
3309 tp = driver->termios[index];
3310 if (tp) {
3311 driver->termios[index] = NULL;
3312 kfree(tp);
3313 }
3314
Johan Hovold6a7e6f72017-03-30 15:39:34 +02003315 retval = tty_cdev_add(driver, devt, index, 1);
3316 if (retval)
3317 goto err_del;
3318 }
3319
3320 dev_set_uevent_suppress(dev, 0);
3321 kobject_uevent(&dev->kobj, KOBJ_ADD);
Tomas Hlavacek6915c0e2012-09-06 03:17:18 +02003322
3323 return dev;
3324
Johan Hovold6a7e6f72017-03-30 15:39:34 +02003325err_del:
3326 device_del(dev);
3327err_put:
Tomas Hlavacek6915c0e2012-09-06 03:17:18 +02003328 put_device(dev);
Johan Hovold6a7e6f72017-03-30 15:39:34 +02003329
Tomas Hlavacek6915c0e2012-09-06 03:17:18 +02003330 return ERR_PTR(retval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003331}
Tomas Hlavacek6915c0e2012-09-06 03:17:18 +02003332EXPORT_SYMBOL_GPL(tty_register_device_attr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003333
3334/**
Xiaofei Tan395e7832021-05-12 17:26:14 +08003335 * tty_unregister_device - unregister a tty device
3336 * @driver: the tty driver that describes the tty device
3337 * @index: the index in the tty driver for this tty device
Linus Torvalds1da177e2005-04-16 15:20:36 -07003338 *
Xiaofei Tan395e7832021-05-12 17:26:14 +08003339 * If a tty device is registered with a call to tty_register_device() then
Alan Coxaf9b8972006-08-27 01:24:01 -07003340 * this function must be called when the tty device is gone.
3341 *
3342 * Locking: ??
Linus Torvalds1da177e2005-04-16 15:20:36 -07003343 */
Alan Coxaf9b8972006-08-27 01:24:01 -07003344
Linus Torvalds1da177e2005-04-16 15:20:36 -07003345void tty_unregister_device(struct tty_driver *driver, unsigned index)
3346{
Alan Cox37bdfb02008-02-08 04:18:47 -08003347 device_destroy(tty_class,
3348 MKDEV(driver->major, driver->minor_start) + index);
Richard Wattsa3a10ce2015-05-19 16:06:53 +01003349 if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) {
3350 cdev_del(driver->cdevs[index]);
3351 driver->cdevs[index] = NULL;
3352 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003353}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003354EXPORT_SYMBOL(tty_unregister_device);
3355
Jiri Slaby7f0bc6a2012-08-07 21:47:42 +02003356/**
3357 * __tty_alloc_driver -- allocate tty driver
3358 * @lines: count of lines this driver can handle at most
Thadeu Lima de Souza Cascardo87838ae2017-04-04 05:56:32 -03003359 * @owner: module which is responsible for this driver
Jiri Slaby7f0bc6a2012-08-07 21:47:42 +02003360 * @flags: some of TTY_DRIVER_* flags, will be set in driver->flags
3361 *
3362 * This should not be called directly, some of the provided macros should be
3363 * used instead. Use IS_ERR and friends on @retval.
3364 */
3365struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner,
3366 unsigned long flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003367{
3368 struct tty_driver *driver;
Jiri Slaby7e73eca2012-08-08 22:26:44 +02003369 unsigned int cdevs = 1;
Jiri Slaby16a02082012-08-08 22:26:42 +02003370 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003371
Jiri Slaby0019b402012-08-08 22:26:43 +02003372 if (!lines || (flags & TTY_DRIVER_UNNUMBERED_NODE && lines > 1))
Jiri Slaby7f0bc6a2012-08-07 21:47:42 +02003373 return ERR_PTR(-EINVAL);
3374
Gustavo A. R. Silvaa3241892020-07-23 17:34:22 -05003375 driver = kzalloc(sizeof(*driver), GFP_KERNEL);
Jiri Slaby7f0bc6a2012-08-07 21:47:42 +02003376 if (!driver)
3377 return ERR_PTR(-ENOMEM);
3378
3379 kref_init(&driver->kref);
3380 driver->magic = TTY_DRIVER_MAGIC;
3381 driver->num = lines;
3382 driver->owner = owner;
3383 driver->flags = flags;
Jiri Slaby16a02082012-08-08 22:26:42 +02003384
3385 if (!(flags & TTY_DRIVER_DEVPTS_MEM)) {
3386 driver->ttys = kcalloc(lines, sizeof(*driver->ttys),
3387 GFP_KERNEL);
3388 driver->termios = kcalloc(lines, sizeof(*driver->termios),
3389 GFP_KERNEL);
3390 if (!driver->ttys || !driver->termios) {
3391 err = -ENOMEM;
3392 goto err_free_all;
3393 }
3394 }
3395
3396 if (!(flags & TTY_DRIVER_DYNAMIC_ALLOC)) {
3397 driver->ports = kcalloc(lines, sizeof(*driver->ports),
3398 GFP_KERNEL);
3399 if (!driver->ports) {
3400 err = -ENOMEM;
3401 goto err_free_all;
3402 }
Jiri Slaby7e73eca2012-08-08 22:26:44 +02003403 cdevs = lines;
3404 }
3405
3406 driver->cdevs = kcalloc(cdevs, sizeof(*driver->cdevs), GFP_KERNEL);
3407 if (!driver->cdevs) {
3408 err = -ENOMEM;
3409 goto err_free_all;
Jiri Slaby16a02082012-08-08 22:26:42 +02003410 }
Jiri Slaby7f0bc6a2012-08-07 21:47:42 +02003411
Linus Torvalds1da177e2005-04-16 15:20:36 -07003412 return driver;
Jiri Slaby16a02082012-08-08 22:26:42 +02003413err_free_all:
3414 kfree(driver->ports);
3415 kfree(driver->ttys);
3416 kfree(driver->termios);
Richard Wattsa3a10ce2015-05-19 16:06:53 +01003417 kfree(driver->cdevs);
Jiri Slaby16a02082012-08-08 22:26:42 +02003418 kfree(driver);
3419 return ERR_PTR(err);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003420}
Jiri Slaby7f0bc6a2012-08-07 21:47:42 +02003421EXPORT_SYMBOL(__tty_alloc_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003422
Alan Cox7d7b93c2008-10-13 10:42:09 +01003423static void destruct_tty_driver(struct kref *kref)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003424{
Alan Cox7d7b93c2008-10-13 10:42:09 +01003425 struct tty_driver *driver = container_of(kref, struct tty_driver, kref);
3426 int i;
3427 struct ktermios *tp;
Alan Cox7d7b93c2008-10-13 10:42:09 +01003428
3429 if (driver->flags & TTY_DRIVER_INSTALLED) {
Alan Cox7d7b93c2008-10-13 10:42:09 +01003430 for (i = 0; i < driver->num; i++) {
3431 tp = driver->termios[i];
3432 if (tp) {
3433 driver->termios[i] = NULL;
3434 kfree(tp);
3435 }
Alan Cox7d7b93c2008-10-13 10:42:09 +01003436 if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV))
3437 tty_unregister_device(driver, i);
3438 }
Alan Cox7d7b93c2008-10-13 10:42:09 +01003439 proc_tty_unregister_driver(driver);
Jiri Slaby7e73eca2012-08-08 22:26:44 +02003440 if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)
Richard Wattsa3a10ce2015-05-19 16:06:53 +01003441 cdev_del(driver->cdevs[0]);
Alan Cox7d7b93c2008-10-13 10:42:09 +01003442 }
Jiri Slaby7e73eca2012-08-08 22:26:44 +02003443 kfree(driver->cdevs);
Jiri Slaby04831dc2012-06-04 13:35:36 +02003444 kfree(driver->ports);
Jiri Slaby16a02082012-08-08 22:26:42 +02003445 kfree(driver->termios);
3446 kfree(driver->ttys);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003447 kfree(driver);
3448}
3449
Alan Cox7d7b93c2008-10-13 10:42:09 +01003450void tty_driver_kref_put(struct tty_driver *driver)
3451{
3452 kref_put(&driver->kref, destruct_tty_driver);
3453}
3454EXPORT_SYMBOL(tty_driver_kref_put);
3455
Jeff Dikeb68e31d2006-10-02 02:17:18 -07003456void tty_set_operations(struct tty_driver *driver,
3457 const struct tty_operations *op)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003458{
Alan Coxf34d7a52008-04-30 00:54:13 -07003459 driver->ops = op;
3460};
Linus Torvalds1da177e2005-04-16 15:20:36 -07003461EXPORT_SYMBOL(tty_set_operations);
3462
Alan Cox7d7b93c2008-10-13 10:42:09 +01003463void put_tty_driver(struct tty_driver *d)
3464{
3465 tty_driver_kref_put(d);
3466}
3467EXPORT_SYMBOL(put_tty_driver);
3468
Linus Torvalds1da177e2005-04-16 15:20:36 -07003469/*
3470 * Called by a tty driver to register itself.
3471 */
3472int tty_register_driver(struct tty_driver *driver)
3473{
3474 int error;
Alan Cox37bdfb02008-02-08 04:18:47 -08003475 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003476 dev_t dev;
Vasiliy Kulikovb670bde2010-09-05 22:32:22 +04003477 struct device *d;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003478
Linus Torvalds1da177e2005-04-16 15:20:36 -07003479 if (!driver->major) {
Alan Cox37bdfb02008-02-08 04:18:47 -08003480 error = alloc_chrdev_region(&dev, driver->minor_start,
3481 driver->num, driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003482 if (!error) {
3483 driver->major = MAJOR(dev);
3484 driver->minor_start = MINOR(dev);
3485 }
3486 } else {
3487 dev = MKDEV(driver->major, driver->minor_start);
Geert Uytterhoevene5717c42007-02-20 15:45:21 +01003488 error = register_chrdev_region(dev, driver->num, driver->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003489 }
Jiri Slaby9bb8a3d2012-06-04 13:35:35 +02003490 if (error < 0)
Jiri Slaby16a02082012-08-08 22:26:42 +02003491 goto err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003492
Jiri Slaby7e73eca2012-08-08 22:26:44 +02003493 if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) {
3494 error = tty_cdev_add(driver, dev, 0, driver->num);
3495 if (error)
3496 goto err_unreg_char;
3497 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003498
Alexey Dobriyanca509f62007-05-08 00:27:12 -07003499 mutex_lock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003500 list_add(&driver->tty_drivers, &tty_drivers);
Alexey Dobriyanca509f62007-05-08 00:27:12 -07003501 mutex_unlock(&tty_mutex);
Alan Cox37bdfb02008-02-08 04:18:47 -08003502
3503 if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) {
Vasiliy Kulikovb670bde2010-09-05 22:32:22 +04003504 for (i = 0; i < driver->num; i++) {
3505 d = tty_register_device(driver, i, NULL);
3506 if (IS_ERR(d)) {
3507 error = PTR_ERR(d);
Jiri Slaby16a02082012-08-08 22:26:42 +02003508 goto err_unreg_devs;
Vasiliy Kulikovb670bde2010-09-05 22:32:22 +04003509 }
3510 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003511 }
3512 proc_tty_register_driver(driver);
Alan Cox7d7b93c2008-10-13 10:42:09 +01003513 driver->flags |= TTY_DRIVER_INSTALLED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003514 return 0;
Vasiliy Kulikovb670bde2010-09-05 22:32:22 +04003515
Jiri Slaby16a02082012-08-08 22:26:42 +02003516err_unreg_devs:
Vasiliy Kulikovb670bde2010-09-05 22:32:22 +04003517 for (i--; i >= 0; i--)
3518 tty_unregister_device(driver, i);
3519
3520 mutex_lock(&tty_mutex);
3521 list_del(&driver->tty_drivers);
3522 mutex_unlock(&tty_mutex);
3523
Jiri Slaby9bb8a3d2012-06-04 13:35:35 +02003524err_unreg_char:
Vasiliy Kulikovb670bde2010-09-05 22:32:22 +04003525 unregister_chrdev_region(dev, driver->num);
Jiri Slaby16a02082012-08-08 22:26:42 +02003526err:
Vasiliy Kulikovb670bde2010-09-05 22:32:22 +04003527 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003528}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003529EXPORT_SYMBOL(tty_register_driver);
3530
3531/*
3532 * Called by a tty driver to unregister itself.
3533 */
Jiri Slabya872ab42021-03-02 07:22:05 +01003534void tty_unregister_driver(struct tty_driver *driver)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003535{
Linus Torvalds1da177e2005-04-16 15:20:36 -07003536 unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
3537 driver->num);
Alexey Dobriyanca509f62007-05-08 00:27:12 -07003538 mutex_lock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003539 list_del(&driver->tty_drivers);
Alexey Dobriyanca509f62007-05-08 00:27:12 -07003540 mutex_unlock(&tty_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003541}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003542EXPORT_SYMBOL(tty_unregister_driver);
3543
Peter Zijlstra24ec8392006-12-08 02:36:04 -08003544dev_t tty_devnum(struct tty_struct *tty)
3545{
3546 return MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index;
3547}
3548EXPORT_SYMBOL(tty_devnum);
3549
Alan Coxd81ed102008-10-13 10:41:42 +01003550void tty_default_fops(struct file_operations *fops)
3551{
3552 *fops = tty_fops;
3553}
3554
Al Viro2c9ede52011-07-23 20:24:48 -04003555static char *tty_devnode(struct device *dev, umode_t *mode)
Kay Sieverse454cea2009-09-18 23:01:12 +02003556{
3557 if (!mode)
3558 return NULL;
3559 if (dev->devt == MKDEV(TTYAUX_MAJOR, 0) ||
3560 dev->devt == MKDEV(TTYAUX_MAJOR, 2))
3561 *mode = 0666;
3562 return NULL;
3563}
3564
Linus Torvalds1da177e2005-04-16 15:20:36 -07003565static int __init tty_class_init(void)
3566{
gregkh@suse.de7fe845d2005-03-15 14:23:15 -08003567 tty_class = class_create(THIS_MODULE, "tty");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003568 if (IS_ERR(tty_class))
3569 return PTR_ERR(tty_class);
Kay Sieverse454cea2009-09-18 23:01:12 +02003570 tty_class->devnode = tty_devnode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003571 return 0;
3572}
3573
3574postcore_initcall(tty_class_init);
3575
3576/* 3/2004 jmc: why do these devices exist? */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003577static struct cdev tty_cdev, console_cdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003578
Kay Sieversfbc92a32010-12-01 18:51:05 +01003579static ssize_t show_cons_active(struct device *dev,
3580 struct device_attribute *attr, char *buf)
3581{
3582 struct console *cs[16];
3583 int i = 0;
3584 struct console *c;
3585 ssize_t count = 0;
3586
Torben Hohnac751ef2011-01-25 15:07:35 -08003587 console_lock();
Kay Sieversa2a6a822011-01-09 16:39:14 +01003588 for_each_console(c) {
Kay Sieversfbc92a32010-12-01 18:51:05 +01003589 if (!c->device)
3590 continue;
3591 if (!c->write)
3592 continue;
3593 if ((c->flags & CON_ENABLED) == 0)
3594 continue;
3595 cs[i++] = c;
3596 if (i >= ARRAY_SIZE(cs))
3597 break;
3598 }
Hannes Reinecke723abd82014-02-27 12:30:51 +01003599 while (i--) {
3600 int index = cs[i]->index;
3601 struct tty_driver *drv = cs[i]->device(cs[i], &index);
3602
3603 /* don't resolve tty0 as some programs depend on it */
3604 if (drv && (cs[i]->index > 0 || drv->major != TTY_MAJOR))
3605 count += tty_line_name(drv, index, buf + count);
3606 else
3607 count += sprintf(buf + count, "%s%d",
3608 cs[i]->name, cs[i]->index);
3609
3610 count += sprintf(buf + count, "%c", i ? ' ':'\n');
3611 }
Torben Hohnac751ef2011-01-25 15:07:35 -08003612 console_unlock();
Kay Sieversfbc92a32010-12-01 18:51:05 +01003613
3614 return count;
3615}
3616static DEVICE_ATTR(active, S_IRUGO, show_cons_active, NULL);
3617
Takashi Iwai1083a7b2015-02-05 11:07:42 +01003618static struct attribute *cons_dev_attrs[] = {
3619 &dev_attr_active.attr,
3620 NULL
3621};
3622
3623ATTRIBUTE_GROUPS(cons_dev);
3624
Kay Sieversfbc92a32010-12-01 18:51:05 +01003625static struct device *consdev;
3626
3627void console_sysfs_notify(void)
3628{
3629 if (consdev)
3630 sysfs_notify(&consdev->kobj, NULL, "active");
3631}
3632
Linus Torvalds1da177e2005-04-16 15:20:36 -07003633/*
3634 * Ok, now we can initialize the rest of the tty devices and can count
3635 * on memory allocations, interrupts etc..
3636 */
David Howells31d1d482010-08-06 16:34:43 +01003637int __init tty_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003638{
Greg Kroah-Hartman7c0cca72019-01-21 17:26:42 +01003639 tty_sysctl_init();
Linus Torvalds1da177e2005-04-16 15:20:36 -07003640 cdev_init(&tty_cdev, &tty_fops);
3641 if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
3642 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
3643 panic("Couldn't register /dev/tty driver\n");
Kay Sieversfbc92a32010-12-01 18:51:05 +01003644 device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003645
3646 cdev_init(&console_cdev, &console_fops);
3647 if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
3648 register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
3649 panic("Couldn't register /dev/console driver\n");
Takashi Iwai1083a7b2015-02-05 11:07:42 +01003650 consdev = device_create_with_groups(tty_class, NULL,
3651 MKDEV(TTYAUX_MAJOR, 1), NULL,
3652 cons_dev_groups, "console");
Kay Sieversfbc92a32010-12-01 18:51:05 +01003653 if (IS_ERR(consdev))
3654 consdev = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003655
Linus Torvalds1da177e2005-04-16 15:20:36 -07003656#ifdef CONFIG_VT
Alan Coxd81ed102008-10-13 10:41:42 +01003657 vty_init(&console_fops);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003658#endif
3659 return 0;
3660}
David Howells31d1d482010-08-06 16:34:43 +01003661