]>
Commit | Line | Data |
---|---|---|
948f2681 GKH |
1 | From 7c0cca7c847e6e019d67b7d793efbbe3b947d004 Mon Sep 17 00:00:00 2001 |
2 | From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
3 | Date: Mon, 21 Jan 2019 17:26:42 +0100 | |
4 | Subject: tty: ldisc: add sysctl to prevent autoloading of ldiscs | |
5 | ||
6 | From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
7 | ||
8 | commit 7c0cca7c847e6e019d67b7d793efbbe3b947d004 upstream. | |
9 | ||
10 | By default, the kernel will automatically load the module of any line | |
11 | dicipline that is asked for. As this sometimes isn't the safest thing | |
12 | to do, provide a sysctl to disable this feature. | |
13 | ||
14 | By default, we set this to 'y' as that is the historical way that Linux | |
15 | has worked, and we do not want to break working systems. But in the | |
16 | future, perhaps this can default to 'n' to prevent this functionality. | |
17 | ||
18 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
19 | Reviewed-by: Theodore Ts'o <tytso@mit.edu> | |
20 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
21 | ||
22 | --- | |
23 | drivers/tty/Kconfig | 24 ++++++++++++++++++++++++ | |
24 | drivers/tty/tty_io.c | 3 +++ | |
25 | drivers/tty/tty_ldisc.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ | |
26 | 3 files changed, 74 insertions(+) | |
27 | ||
28 | --- a/drivers/tty/Kconfig | |
29 | +++ b/drivers/tty/Kconfig | |
30 | @@ -441,4 +441,28 @@ config VCC | |
31 | depends on SUN_LDOMS | |
32 | help | |
33 | Support for Sun logical domain consoles. | |
34 | + | |
35 | +config LDISC_AUTOLOAD | |
36 | + bool "Automatically load TTY Line Disciplines" | |
37 | + default y | |
38 | + help | |
39 | + Historically the kernel has always automatically loaded any | |
40 | + line discipline that is in a kernel module when a user asks | |
41 | + for it to be loaded with the TIOCSETD ioctl, or through other | |
42 | + means. This is not always the best thing to do on systems | |
43 | + where you know you will not be using some of the more | |
44 | + "ancient" line disciplines, so prevent the kernel from doing | |
45 | + this unless the request is coming from a process with the | |
46 | + CAP_SYS_MODULE permissions. | |
47 | + | |
48 | + Say 'Y' here if you trust your userspace users to do the right | |
49 | + thing, or if you have only provided the line disciplines that | |
50 | + you know you will be using, or if you wish to continue to use | |
51 | + the traditional method of on-demand loading of these modules | |
52 | + by any user. | |
53 | + | |
54 | + This functionality can be changed at runtime with the | |
55 | + dev.tty.ldisc_autoload sysctl, this configuration option will | |
56 | + only set the default value of this functionality. | |
57 | + | |
58 | endif # TTY | |
59 | --- a/drivers/tty/tty_io.c | |
60 | +++ b/drivers/tty/tty_io.c | |
61 | @@ -512,6 +512,8 @@ static const struct file_operations hung | |
62 | static DEFINE_SPINLOCK(redirect_lock); | |
63 | static struct file *redirect; | |
64 | ||
65 | +extern void tty_sysctl_init(void); | |
66 | + | |
67 | /** | |
68 | * tty_wakeup - request more data | |
69 | * @tty: terminal | |
70 | @@ -3340,6 +3342,7 @@ void console_sysfs_notify(void) | |
71 | */ | |
72 | int __init tty_init(void) | |
73 | { | |
74 | + tty_sysctl_init(); | |
75 | cdev_init(&tty_cdev, &tty_fops); | |
76 | if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) || | |
77 | register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) | |
78 | --- a/drivers/tty/tty_ldisc.c | |
79 | +++ b/drivers/tty/tty_ldisc.c | |
80 | @@ -156,6 +156,13 @@ static void put_ldops(struct tty_ldisc_o | |
81 | * takes tty_ldiscs_lock to guard against ldisc races | |
82 | */ | |
83 | ||
84 | +#if defined(CONFIG_LDISC_AUTOLOAD) | |
85 | + #define INITIAL_AUTOLOAD_STATE 1 | |
86 | +#else | |
87 | + #define INITIAL_AUTOLOAD_STATE 0 | |
88 | +#endif | |
89 | +static int tty_ldisc_autoload = INITIAL_AUTOLOAD_STATE; | |
90 | + | |
91 | static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc) | |
92 | { | |
93 | struct tty_ldisc *ld; | |
94 | @@ -170,6 +177,8 @@ static struct tty_ldisc *tty_ldisc_get(s | |
95 | */ | |
96 | ldops = get_ldops(disc); | |
97 | if (IS_ERR(ldops)) { | |
98 | + if (!capable(CAP_SYS_MODULE) && !tty_ldisc_autoload) | |
99 | + return ERR_PTR(-EPERM); | |
100 | request_module("tty-ldisc-%d", disc); | |
101 | ldops = get_ldops(disc); | |
102 | if (IS_ERR(ldops)) | |
103 | @@ -829,3 +838,41 @@ void tty_ldisc_deinit(struct tty_struct | |
104 | tty_ldisc_put(tty->ldisc); | |
105 | tty->ldisc = NULL; | |
106 | } | |
107 | + | |
108 | +static int zero; | |
109 | +static int one = 1; | |
110 | +static struct ctl_table tty_table[] = { | |
111 | + { | |
112 | + .procname = "ldisc_autoload", | |
113 | + .data = &tty_ldisc_autoload, | |
114 | + .maxlen = sizeof(tty_ldisc_autoload), | |
115 | + .mode = 0644, | |
116 | + .proc_handler = proc_dointvec, | |
117 | + .extra1 = &zero, | |
118 | + .extra2 = &one, | |
119 | + }, | |
120 | + { } | |
121 | +}; | |
122 | + | |
123 | +static struct ctl_table tty_dir_table[] = { | |
124 | + { | |
125 | + .procname = "tty", | |
126 | + .mode = 0555, | |
127 | + .child = tty_table, | |
128 | + }, | |
129 | + { } | |
130 | +}; | |
131 | + | |
132 | +static struct ctl_table tty_root_table[] = { | |
133 | + { | |
134 | + .procname = "dev", | |
135 | + .mode = 0555, | |
136 | + .child = tty_dir_table, | |
137 | + }, | |
138 | + { } | |
139 | +}; | |
140 | + | |
141 | +void tty_sysctl_init(void) | |
142 | +{ | |
143 | + register_sysctl_table(tty_root_table); | |
144 | +} |