Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : /*
3 : : * Copyright (C) 1991, 1992 Linus Torvalds
4 : : */
5 : :
6 : : #include <linux/types.h>
7 : : #include <linux/errno.h>
8 : : #include <linux/signal.h>
9 : : #include <linux/sched/signal.h>
10 : : #include <linux/sched/task.h>
11 : : #include <linux/tty.h>
12 : : #include <linux/fcntl.h>
13 : : #include <linux/uaccess.h>
14 : :
15 : 0 : static int is_ignored(int sig)
16 : : {
17 : 0 : return (sigismember(¤t->blocked, sig) ||
18 [ # # ]: 0 : current->sighand->action[sig-1].sa.sa_handler == SIG_IGN);
19 : : }
20 : :
21 : : /**
22 : : * tty_check_change - check for POSIX terminal changes
23 : : * @tty: tty to check
24 : : *
25 : : * If we try to write to, or set the state of, a terminal and we're
26 : : * not in the foreground, send a SIGTTOU. If the signal is blocked or
27 : : * ignored, go ahead and perform the operation. (POSIX 7.2)
28 : : *
29 : : * Locking: ctrl_lock
30 : : */
31 : 156 : int __tty_check_change(struct tty_struct *tty, int sig)
32 : : {
33 : 156 : unsigned long flags;
34 : 156 : struct pid *pgrp, *tty_pgrp;
35 : 156 : int ret = 0;
36 : :
37 [ - + ]: 156 : if (current->signal->tty != tty)
38 : : return 0;
39 : :
40 : 0 : rcu_read_lock();
41 : 0 : pgrp = task_pgrp(current);
42 : :
43 : 0 : spin_lock_irqsave(&tty->ctrl_lock, flags);
44 : 0 : tty_pgrp = tty->pgrp;
45 : 0 : spin_unlock_irqrestore(&tty->ctrl_lock, flags);
46 : :
47 [ # # ]: 0 : if (tty_pgrp && pgrp != tty_pgrp) {
48 [ # # ]: 0 : if (is_ignored(sig)) {
49 [ # # ]: 0 : if (sig == SIGTTIN)
50 : 0 : ret = -EIO;
51 [ # # ]: 0 : } else if (is_current_pgrp_orphaned())
52 : : ret = -EIO;
53 : : else {
54 : 0 : kill_pgrp(pgrp, sig, 1);
55 : 0 : set_thread_flag(TIF_SIGPENDING);
56 : 0 : ret = -ERESTARTSYS;
57 : : }
58 : : }
59 : 0 : rcu_read_unlock();
60 : :
61 [ # # ]: 0 : if (!tty_pgrp)
62 : 0 : tty_warn(tty, "sig=%d, tty->pgrp == NULL!\n", sig);
63 : :
64 : : return ret;
65 : : }
66 : :
67 : 156 : int tty_check_change(struct tty_struct *tty)
68 : : {
69 : 156 : return __tty_check_change(tty, SIGTTOU);
70 : : }
71 : : EXPORT_SYMBOL(tty_check_change);
72 : :
73 : 1872 : void proc_clear_tty(struct task_struct *p)
74 : : {
75 : 1872 : unsigned long flags;
76 : 1872 : struct tty_struct *tty;
77 : 1872 : spin_lock_irqsave(&p->sighand->siglock, flags);
78 : 1872 : tty = p->signal->tty;
79 : 1872 : p->signal->tty = NULL;
80 : 1872 : spin_unlock_irqrestore(&p->sighand->siglock, flags);
81 : 1872 : tty_kref_put(tty);
82 : 1872 : }
83 : :
84 : : /**
85 : : * proc_set_tty - set the controlling terminal
86 : : *
87 : : * Only callable by the session leader and only if it does not already have
88 : : * a controlling terminal.
89 : : *
90 : : * Caller must hold: tty_lock()
91 : : * a readlock on tasklist_lock
92 : : * sighand lock
93 : : */
94 : 0 : static void __proc_set_tty(struct tty_struct *tty)
95 : : {
96 : 0 : unsigned long flags;
97 : :
98 : 0 : spin_lock_irqsave(&tty->ctrl_lock, flags);
99 : : /*
100 : : * The session and fg pgrp references will be non-NULL if
101 : : * tiocsctty() is stealing the controlling tty
102 : : */
103 : 0 : put_pid(tty->session);
104 : 0 : put_pid(tty->pgrp);
105 [ # # ]: 0 : tty->pgrp = get_pid(task_pgrp(current));
106 : 0 : spin_unlock_irqrestore(&tty->ctrl_lock, flags);
107 [ # # ]: 0 : tty->session = get_pid(task_session(current));
108 [ # # ]: 0 : if (current->signal->tty) {
109 : 0 : tty_debug(tty, "current tty %s not NULL!!\n",
110 : : current->signal->tty->name);
111 : 0 : tty_kref_put(current->signal->tty);
112 : : }
113 : 0 : put_pid(current->signal->tty_old_pgrp);
114 [ # # ]: 0 : current->signal->tty = tty_kref_get(tty);
115 : 0 : current->signal->tty_old_pgrp = NULL;
116 : 0 : }
117 : :
118 : 0 : static void proc_set_tty(struct tty_struct *tty)
119 : : {
120 : 0 : spin_lock_irq(¤t->sighand->siglock);
121 : 0 : __proc_set_tty(tty);
122 : 0 : spin_unlock_irq(¤t->sighand->siglock);
123 : 0 : }
124 : :
125 : : /*
126 : : * Called by tty_open() to set the controlling tty if applicable.
127 : : */
128 : 0 : void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty)
129 : : {
130 : 0 : read_lock(&tasklist_lock);
131 : 0 : spin_lock_irq(¤t->sighand->siglock);
132 [ # # ]: 0 : if (current->signal->leader &&
133 [ # # ]: 0 : !current->signal->tty &&
134 [ # # ]: 0 : tty->session == NULL) {
135 : : /*
136 : : * Don't let a process that only has write access to the tty
137 : : * obtain the privileges associated with having a tty as
138 : : * controlling terminal (being able to reopen it with full
139 : : * access through /dev/tty, being able to perform pushback).
140 : : * Many distributions set the group of all ttys to "tty" and
141 : : * grant write-only access to all terminals for setgid tty
142 : : * binaries, which should not imply full privileges on all ttys.
143 : : *
144 : : * This could theoretically break old code that performs open()
145 : : * on a write-only file descriptor. In that case, it might be
146 : : * necessary to also permit this if
147 : : * inode_permission(inode, MAY_READ) == 0.
148 : : */
149 [ # # ]: 0 : if (filp->f_mode & FMODE_READ)
150 : 0 : __proc_set_tty(tty);
151 : : }
152 : 0 : spin_unlock_irq(¤t->sighand->siglock);
153 : 0 : read_unlock(&tasklist_lock);
154 : 0 : }
155 : :
156 : 1794 : struct tty_struct *get_current_tty(void)
157 : : {
158 : 1794 : struct tty_struct *tty;
159 : 1794 : unsigned long flags;
160 : :
161 : 1794 : spin_lock_irqsave(¤t->sighand->siglock, flags);
162 [ - + ]: 1794 : tty = tty_kref_get(current->signal->tty);
163 : 1794 : spin_unlock_irqrestore(¤t->sighand->siglock, flags);
164 : 1794 : return tty;
165 : : }
166 : : EXPORT_SYMBOL_GPL(get_current_tty);
167 : :
168 : : /*
169 : : * Called from tty_release().
170 : : */
171 : 7044 : void session_clear_tty(struct pid *session)
172 : : {
173 : 7044 : struct task_struct *p;
174 [ - + - - : 7044 : do_each_pid_task(session, PIDTYPE_SID, p) {
- - ]
175 : 0 : proc_clear_tty(p);
176 [ # # ]: 0 : } while_each_pid_task(session, PIDTYPE_SID, p);
177 : 7044 : }
178 : :
179 : : /**
180 : : * tty_signal_session_leader - sends SIGHUP to session leader
181 : : * @tty controlling tty
182 : : * @exit_session if non-zero, signal all foreground group processes
183 : : *
184 : : * Send SIGHUP and SIGCONT to the session leader and its process group.
185 : : * Optionally, signal all processes in the foreground process group.
186 : : *
187 : : * Returns the number of processes in the session with this tty
188 : : * as their controlling terminal. This value is used to drop
189 : : * tty references for those processes.
190 : : */
191 : 0 : int tty_signal_session_leader(struct tty_struct *tty, int exit_session)
192 : : {
193 : 0 : struct task_struct *p;
194 : 0 : int refs = 0;
195 : 0 : struct pid *tty_pgrp = NULL;
196 : :
197 : 0 : read_lock(&tasklist_lock);
198 [ # # ]: 0 : if (tty->session) {
199 [ # # # # : 0 : do_each_pid_task(tty->session, PIDTYPE_SID, p) {
# # ]
200 : 0 : spin_lock_irq(&p->sighand->siglock);
201 [ # # ]: 0 : if (p->signal->tty == tty) {
202 : 0 : p->signal->tty = NULL;
203 : : /* We defer the dereferences outside fo
204 : : the tasklist lock */
205 : 0 : refs++;
206 : : }
207 [ # # ]: 0 : if (!p->signal->leader) {
208 : 0 : spin_unlock_irq(&p->sighand->siglock);
209 : 0 : continue;
210 : : }
211 : 0 : __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
212 : 0 : __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
213 : 0 : put_pid(p->signal->tty_old_pgrp); /* A noop */
214 : 0 : spin_lock(&tty->ctrl_lock);
215 [ # # ]: 0 : tty_pgrp = get_pid(tty->pgrp);
216 [ # # ]: 0 : if (tty->pgrp)
217 : 0 : p->signal->tty_old_pgrp = get_pid(tty->pgrp);
218 : 0 : spin_unlock(&tty->ctrl_lock);
219 : 0 : spin_unlock_irq(&p->sighand->siglock);
220 : 0 : } while_each_pid_task(tty->session, PIDTYPE_SID, p);
221 : : }
222 : 0 : read_unlock(&tasklist_lock);
223 : :
224 [ # # ]: 0 : if (tty_pgrp) {
225 [ # # ]: 0 : if (exit_session)
226 : 0 : kill_pgrp(tty_pgrp, SIGHUP, exit_session);
227 : 0 : put_pid(tty_pgrp);
228 : : }
229 : :
230 : 0 : return refs;
231 : : }
232 : :
233 : : /**
234 : : * disassociate_ctty - disconnect controlling tty
235 : : * @on_exit: true if exiting so need to "hang up" the session
236 : : *
237 : : * This function is typically called only by the session leader, when
238 : : * it wants to disassociate itself from its controlling tty.
239 : : *
240 : : * It performs the following functions:
241 : : * (1) Sends a SIGHUP and SIGCONT to the foreground process group
242 : : * (2) Clears the tty from being controlling the session
243 : : * (3) Clears the controlling tty for all processes in the
244 : : * session group.
245 : : *
246 : : * The argument on_exit is set to 1 if called when a process is
247 : : * exiting; it is 0 if called by the ioctl TIOCNOTTY.
248 : : *
249 : : * Locking:
250 : : * BTM is taken for hysterical raisons, and held when
251 : : * called from no_tty().
252 : : * tty_mutex is taken to protect tty
253 : : * ->siglock is taken to protect ->signal/->sighand
254 : : * tasklist_lock is taken to walk process list for sessions
255 : : * ->siglock is taken to protect ->signal/->sighand
256 : : */
257 : 188597 : void disassociate_ctty(int on_exit)
258 : : {
259 : 188597 : struct tty_struct *tty;
260 : :
261 [ + + ]: 188597 : if (!current->signal->leader)
262 : : return;
263 : :
264 : 1248 : tty = get_current_tty();
265 [ - + ]: 1248 : if (tty) {
266 [ # # # # ]: 0 : if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) {
267 : 0 : tty_vhangup_session(tty);
268 : : } else {
269 : 0 : struct pid *tty_pgrp = tty_get_pgrp(tty);
270 [ # # ]: 0 : if (tty_pgrp) {
271 : 0 : kill_pgrp(tty_pgrp, SIGHUP, on_exit);
272 [ # # ]: 0 : if (!on_exit)
273 : 0 : kill_pgrp(tty_pgrp, SIGCONT, on_exit);
274 : 0 : put_pid(tty_pgrp);
275 : : }
276 : : }
277 : 0 : tty_kref_put(tty);
278 : :
279 [ + - ]: 1248 : } else if (on_exit) {
280 : 1248 : struct pid *old_pgrp;
281 : 1248 : spin_lock_irq(¤t->sighand->siglock);
282 : 1248 : old_pgrp = current->signal->tty_old_pgrp;
283 : 1248 : current->signal->tty_old_pgrp = NULL;
284 : 1248 : spin_unlock_irq(¤t->sighand->siglock);
285 [ - + ]: 1248 : if (old_pgrp) {
286 : 0 : kill_pgrp(old_pgrp, SIGHUP, on_exit);
287 : 0 : kill_pgrp(old_pgrp, SIGCONT, on_exit);
288 : 0 : put_pid(old_pgrp);
289 : : }
290 : 1248 : return;
291 : : }
292 : :
293 : 0 : spin_lock_irq(¤t->sighand->siglock);
294 : 0 : put_pid(current->signal->tty_old_pgrp);
295 [ # # ]: 0 : current->signal->tty_old_pgrp = NULL;
296 : :
297 [ # # ]: 0 : tty = tty_kref_get(current->signal->tty);
298 [ # # ]: 0 : if (tty) {
299 : 0 : unsigned long flags;
300 : 0 : spin_lock_irqsave(&tty->ctrl_lock, flags);
301 : 0 : put_pid(tty->session);
302 : 0 : put_pid(tty->pgrp);
303 : 0 : tty->session = NULL;
304 : 0 : tty->pgrp = NULL;
305 : 0 : spin_unlock_irqrestore(&tty->ctrl_lock, flags);
306 : 0 : tty_kref_put(tty);
307 : : }
308 : :
309 : 0 : spin_unlock_irq(¤t->sighand->siglock);
310 : : /* Now clear signal->tty under the lock */
311 : 0 : read_lock(&tasklist_lock);
312 : 0 : session_clear_tty(task_session(current));
313 : 0 : read_unlock(&tasklist_lock);
314 : : }
315 : :
316 : : /*
317 : : *
318 : : * no_tty - Ensure the current process does not have a controlling tty
319 : : */
320 : 0 : void no_tty(void)
321 : : {
322 : : /* FIXME: Review locking here. The tty_lock never covered any race
323 : : between a new association and proc_clear_tty but possible we need
324 : : to protect against this anyway */
325 : 0 : struct task_struct *tsk = current;
326 : 0 : disassociate_ctty(0);
327 : 0 : proc_clear_tty(tsk);
328 : 0 : }
329 : :
330 : : /**
331 : : * tiocsctty - set controlling tty
332 : : * @tty: tty structure
333 : : * @arg: user argument
334 : : *
335 : : * This ioctl is used to manage job control. It permits a session
336 : : * leader to set this tty as the controlling tty for the session.
337 : : *
338 : : * Locking:
339 : : * Takes tty_lock() to serialize proc_set_tty() for this tty
340 : : * Takes tasklist_lock internally to walk sessions
341 : : * Takes ->siglock() when updating signal->tty
342 : : */
343 : : static int tiocsctty(struct tty_struct *tty, struct file *file, int arg)
344 : : {
345 : : int ret = 0;
346 : :
347 : : tty_lock(tty);
348 : : read_lock(&tasklist_lock);
349 : :
350 : : if (current->signal->leader && (task_session(current) == tty->session))
351 : : goto unlock;
352 : :
353 : : /*
354 : : * The process must be a session leader and
355 : : * not have a controlling tty already.
356 : : */
357 : : if (!current->signal->leader || current->signal->tty) {
358 : : ret = -EPERM;
359 : : goto unlock;
360 : : }
361 : :
362 : : if (tty->session) {
363 : : /*
364 : : * This tty is already the controlling
365 : : * tty for another session group!
366 : : */
367 : : if (arg == 1 && capable(CAP_SYS_ADMIN)) {
368 : : /*
369 : : * Steal it away
370 : : */
371 : : session_clear_tty(tty->session);
372 : : } else {
373 : : ret = -EPERM;
374 : : goto unlock;
375 : : }
376 : : }
377 : :
378 : : /* See the comment in tty_open_proc_set_tty(). */
379 : : if ((file->f_mode & FMODE_READ) == 0 && !capable(CAP_SYS_ADMIN)) {
380 : : ret = -EPERM;
381 : : goto unlock;
382 : : }
383 : :
384 : : proc_set_tty(tty);
385 : : unlock:
386 : : read_unlock(&tasklist_lock);
387 : : tty_unlock(tty);
388 : : return ret;
389 : : }
390 : :
391 : : /**
392 : : * tty_get_pgrp - return a ref counted pgrp pid
393 : : * @tty: tty to read
394 : : *
395 : : * Returns a refcounted instance of the pid struct for the process
396 : : * group controlling the tty.
397 : : */
398 : 0 : struct pid *tty_get_pgrp(struct tty_struct *tty)
399 : : {
400 : 0 : unsigned long flags;
401 : 0 : struct pid *pgrp;
402 : :
403 : 0 : spin_lock_irqsave(&tty->ctrl_lock, flags);
404 [ # # ]: 0 : pgrp = get_pid(tty->pgrp);
405 : 0 : spin_unlock_irqrestore(&tty->ctrl_lock, flags);
406 : :
407 : 0 : return pgrp;
408 : : }
409 : : EXPORT_SYMBOL_GPL(tty_get_pgrp);
410 : :
411 : : /*
412 : : * This checks not only the pgrp, but falls back on the pid if no
413 : : * satisfactory pgrp is found. I dunno - gdb doesn't work correctly
414 : : * without this...
415 : : *
416 : : * The caller must hold rcu lock or the tasklist lock.
417 : : */
418 : 0 : static struct pid *session_of_pgrp(struct pid *pgrp)
419 : : {
420 : 0 : struct task_struct *p;
421 : 0 : struct pid *sid = NULL;
422 : :
423 : 0 : p = pid_task(pgrp, PIDTYPE_PGID);
424 [ # # ]: 0 : if (p == NULL)
425 : 0 : p = pid_task(pgrp, PIDTYPE_PID);
426 [ # # ]: 0 : if (p != NULL)
427 : 0 : sid = task_session(p);
428 : :
429 : 0 : return sid;
430 : : }
431 : :
432 : : /**
433 : : * tiocgpgrp - get process group
434 : : * @tty: tty passed by user
435 : : * @real_tty: tty side of the tty passed by the user if a pty else the tty
436 : : * @p: returned pid
437 : : *
438 : : * Obtain the process group of the tty. If there is no process group
439 : : * return an error.
440 : : *
441 : : * Locking: none. Reference to current->signal->tty is safe.
442 : : */
443 : 0 : static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
444 : : {
445 : 0 : struct pid *pid;
446 : 0 : int ret;
447 : : /*
448 : : * (tty == real_tty) is a cheap way of
449 : : * testing if the tty is NOT a master pty.
450 : : */
451 [ # # # # ]: 0 : if (tty == real_tty && current->signal->tty != real_tty)
452 : : return -ENOTTY;
453 : 0 : pid = tty_get_pgrp(real_tty);
454 : 0 : ret = put_user(pid_vnr(pid), p);
455 : 0 : put_pid(pid);
456 : 0 : return ret;
457 : : }
458 : :
459 : : /**
460 : : * tiocspgrp - attempt to set process group
461 : : * @tty: tty passed by user
462 : : * @real_tty: tty side device matching tty passed by user
463 : : * @p: pid pointer
464 : : *
465 : : * Set the process group of the tty to the session passed. Only
466 : : * permitted where the tty session is our session.
467 : : *
468 : : * Locking: RCU, ctrl lock
469 : : */
470 : 0 : static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
471 : : {
472 : 0 : struct pid *pgrp;
473 : 0 : pid_t pgrp_nr;
474 : 0 : int retval = tty_check_change(real_tty);
475 : :
476 [ # # ]: 0 : if (retval == -EIO)
477 : : return -ENOTTY;
478 [ # # ]: 0 : if (retval)
479 : : return retval;
480 [ # # ]: 0 : if (!current->signal->tty ||
481 [ # # # # ]: 0 : (current->signal->tty != real_tty) ||
482 [ # # ]: 0 : (real_tty->session != task_session(current)))
483 : : return -ENOTTY;
484 [ # # ]: 0 : if (get_user(pgrp_nr, p))
485 : : return -EFAULT;
486 [ # # ]: 0 : if (pgrp_nr < 0)
487 : : return -EINVAL;
488 : 0 : rcu_read_lock();
489 : 0 : pgrp = find_vpid(pgrp_nr);
490 : 0 : retval = -ESRCH;
491 [ # # ]: 0 : if (!pgrp)
492 : 0 : goto out_unlock;
493 : 0 : retval = -EPERM;
494 [ # # ]: 0 : if (session_of_pgrp(pgrp) != task_session(current))
495 : 0 : goto out_unlock;
496 : 0 : retval = 0;
497 : 0 : spin_lock_irq(&tty->ctrl_lock);
498 : 0 : put_pid(real_tty->pgrp);
499 : 0 : real_tty->pgrp = get_pid(pgrp);
500 : 0 : spin_unlock_irq(&tty->ctrl_lock);
501 : 0 : out_unlock:
502 : 0 : rcu_read_unlock();
503 : 0 : return retval;
504 : : }
505 : :
506 : : /**
507 : : * tiocgsid - get session id
508 : : * @tty: tty passed by user
509 : : * @real_tty: tty side of the tty passed by the user if a pty else the tty
510 : : * @p: pointer to returned session id
511 : : *
512 : : * Obtain the session id of the tty. If there is no session
513 : : * return an error.
514 : : *
515 : : * Locking: none. Reference to current->signal->tty is safe.
516 : : */
517 : 0 : static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
518 : : {
519 : : /*
520 : : * (tty == real_tty) is a cheap way of
521 : : * testing if the tty is NOT a master pty.
522 : : */
523 [ # # # # ]: 0 : if (tty == real_tty && current->signal->tty != real_tty)
524 : : return -ENOTTY;
525 [ # # ]: 0 : if (!real_tty->session)
526 : : return -ENOTTY;
527 : 0 : return put_user(pid_vnr(real_tty->session), p);
528 : : }
529 : :
530 : : /*
531 : : * Called from tty_ioctl(). If tty is a pty then real_tty is the slave side,
532 : : * if not then tty == real_tty.
533 : : */
534 : 7443 : long tty_jobctrl_ioctl(struct tty_struct *tty, struct tty_struct *real_tty,
535 : : struct file *file, unsigned int cmd, unsigned long arg)
536 : : {
537 : 7443 : void __user *p = (void __user *)arg;
538 : :
539 [ - - - - : 7443 : switch (cmd) {
- + ]
540 : : case TIOCNOTTY:
541 [ # # ]: 0 : if (current->signal->tty != tty)
542 : : return -ENOTTY;
543 : 0 : no_tty();
544 : 0 : return 0;
545 : 0 : case TIOCSCTTY:
546 : 0 : return tiocsctty(real_tty, file, arg);
547 : 0 : case TIOCGPGRP:
548 : 0 : return tiocgpgrp(tty, real_tty, p);
549 : 0 : case TIOCSPGRP:
550 : 0 : return tiocspgrp(tty, real_tty, p);
551 : 0 : case TIOCGSID:
552 : 0 : return tiocgsid(tty, real_tty, p);
553 : : }
554 : : return -ENOIOCTLCMD;
555 : : }
|