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