| .. | .. |
|---|
| 87 | 87 | #include <linux/string.h> |
|---|
| 88 | 88 | #include <linux/slab.h> |
|---|
| 89 | 89 | #include <linux/poll.h> |
|---|
| 90 | +#include <linux/ppp-ioctl.h> |
|---|
| 90 | 91 | #include <linux/proc_fs.h> |
|---|
| 91 | 92 | #include <linux/init.h> |
|---|
| 92 | 93 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 97 | 98 | #include <linux/seq_file.h> |
|---|
| 98 | 99 | #include <linux/serial.h> |
|---|
| 99 | 100 | #include <linux/ratelimit.h> |
|---|
| 101 | +#include <linux/compat.h> |
|---|
| 100 | 102 | |
|---|
| 101 | 103 | #include <linux/uaccess.h> |
|---|
| 102 | 104 | |
|---|
| .. | .. |
|---|
| 140 | 142 | /* Mutex to protect creating and releasing a tty */ |
|---|
| 141 | 143 | DEFINE_MUTEX(tty_mutex); |
|---|
| 142 | 144 | |
|---|
| 143 | | -static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); |
|---|
| 144 | | -static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); |
|---|
| 145 | | -ssize_t redirected_tty_write(struct file *, const char __user *, |
|---|
| 146 | | - size_t, loff_t *); |
|---|
| 145 | +static ssize_t tty_read(struct kiocb *, struct iov_iter *); |
|---|
| 146 | +static ssize_t tty_write(struct kiocb *, struct iov_iter *); |
|---|
| 147 | 147 | static __poll_t tty_poll(struct file *, poll_table *); |
|---|
| 148 | 148 | static int tty_open(struct inode *, struct file *); |
|---|
| 149 | | -long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
|---|
| 150 | 149 | #ifdef CONFIG_COMPAT |
|---|
| 151 | 150 | static long tty_compat_ioctl(struct file *file, unsigned int cmd, |
|---|
| 152 | 151 | unsigned long arg); |
|---|
| .. | .. |
|---|
| 305 | 304 | |
|---|
| 306 | 305 | /** |
|---|
| 307 | 306 | * get_tty_driver - find device of a tty |
|---|
| 308 | | - * @dev_t: device identifier |
|---|
| 307 | + * @device: device identifier |
|---|
| 309 | 308 | * @index: returns the index of the tty |
|---|
| 310 | 309 | * |
|---|
| 311 | 310 | * This routine returns a tty driver structure, given a device number |
|---|
| .. | .. |
|---|
| 430 | 429 | EXPORT_SYMBOL_GPL(tty_find_polling_driver); |
|---|
| 431 | 430 | #endif |
|---|
| 432 | 431 | |
|---|
| 433 | | -static ssize_t hung_up_tty_read(struct file *file, char __user *buf, |
|---|
| 434 | | - size_t count, loff_t *ppos) |
|---|
| 432 | +static ssize_t hung_up_tty_read(struct kiocb *iocb, struct iov_iter *to) |
|---|
| 435 | 433 | { |
|---|
| 436 | 434 | return 0; |
|---|
| 437 | 435 | } |
|---|
| 438 | 436 | |
|---|
| 439 | | -static ssize_t hung_up_tty_write(struct file *file, const char __user *buf, |
|---|
| 440 | | - size_t count, loff_t *ppos) |
|---|
| 437 | +static ssize_t hung_up_tty_write(struct kiocb *iocb, struct iov_iter *from) |
|---|
| 441 | 438 | { |
|---|
| 442 | 439 | return -EIO; |
|---|
| 443 | 440 | } |
|---|
| .. | .. |
|---|
| 475 | 472 | |
|---|
| 476 | 473 | static const struct file_operations tty_fops = { |
|---|
| 477 | 474 | .llseek = no_llseek, |
|---|
| 478 | | - .read = tty_read, |
|---|
| 479 | | - .write = tty_write, |
|---|
| 475 | + .read_iter = tty_read, |
|---|
| 476 | + .write_iter = tty_write, |
|---|
| 477 | + .splice_read = generic_file_splice_read, |
|---|
| 478 | + .splice_write = iter_file_splice_write, |
|---|
| 480 | 479 | .poll = tty_poll, |
|---|
| 481 | 480 | .unlocked_ioctl = tty_ioctl, |
|---|
| 482 | 481 | .compat_ioctl = tty_compat_ioctl, |
|---|
| .. | .. |
|---|
| 488 | 487 | |
|---|
| 489 | 488 | static const struct file_operations console_fops = { |
|---|
| 490 | 489 | .llseek = no_llseek, |
|---|
| 491 | | - .read = tty_read, |
|---|
| 492 | | - .write = redirected_tty_write, |
|---|
| 490 | + .read_iter = tty_read, |
|---|
| 491 | + .write_iter = redirected_tty_write, |
|---|
| 492 | + .splice_read = generic_file_splice_read, |
|---|
| 493 | + .splice_write = iter_file_splice_write, |
|---|
| 493 | 494 | .poll = tty_poll, |
|---|
| 494 | 495 | .unlocked_ioctl = tty_ioctl, |
|---|
| 495 | 496 | .compat_ioctl = tty_compat_ioctl, |
|---|
| .. | .. |
|---|
| 500 | 501 | |
|---|
| 501 | 502 | static const struct file_operations hung_up_tty_fops = { |
|---|
| 502 | 503 | .llseek = no_llseek, |
|---|
| 503 | | - .read = hung_up_tty_read, |
|---|
| 504 | | - .write = hung_up_tty_write, |
|---|
| 504 | + .read_iter = hung_up_tty_read, |
|---|
| 505 | + .write_iter = hung_up_tty_write, |
|---|
| 505 | 506 | .poll = hung_up_tty_poll, |
|---|
| 506 | 507 | .unlocked_ioctl = hung_up_tty_ioctl, |
|---|
| 507 | 508 | .compat_ioctl = hung_up_tty_compat_ioctl, |
|---|
| .. | .. |
|---|
| 542 | 543 | |
|---|
| 543 | 544 | /** |
|---|
| 544 | 545 | * __tty_hangup - actual handler for hangup events |
|---|
| 545 | | - * @work: tty device |
|---|
| 546 | + * @tty: tty device |
|---|
| 546 | 547 | * |
|---|
| 547 | 548 | * This can be called by a "kworker" kernel thread. That is process |
|---|
| 548 | 549 | * synchronous but doesn't hold any locks, so we need to make sure we |
|---|
| .. | .. |
|---|
| 605 | 606 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ |
|---|
| 606 | 607 | list_for_each_entry(priv, &tty->tty_files, list) { |
|---|
| 607 | 608 | filp = priv->file; |
|---|
| 608 | | - if (filp->f_op->write == redirected_tty_write) |
|---|
| 609 | + if (filp->f_op->write_iter == redirected_tty_write) |
|---|
| 609 | 610 | cons_filp = filp; |
|---|
| 610 | | - if (filp->f_op->write != tty_write) |
|---|
| 611 | + if (filp->f_op->write_iter != tty_write) |
|---|
| 611 | 612 | continue; |
|---|
| 612 | 613 | closecount++; |
|---|
| 613 | 614 | __tty_fasync(-1, filp, 0); /* can't block */ |
|---|
| .. | .. |
|---|
| 830 | 831 | time->tv_sec = sec; |
|---|
| 831 | 832 | } |
|---|
| 832 | 833 | |
|---|
| 834 | +/* |
|---|
| 835 | + * Iterate on the ldisc ->read() function until we've gotten all |
|---|
| 836 | + * the data the ldisc has for us. |
|---|
| 837 | + * |
|---|
| 838 | + * The "cookie" is something that the ldisc read function can fill |
|---|
| 839 | + * in to let us know that there is more data to be had. |
|---|
| 840 | + * |
|---|
| 841 | + * We promise to continue to call the ldisc until it stops returning |
|---|
| 842 | + * data or clears the cookie. The cookie may be something that the |
|---|
| 843 | + * ldisc maintains state for and needs to free. |
|---|
| 844 | + */ |
|---|
| 845 | +static int iterate_tty_read(struct tty_ldisc *ld, struct tty_struct *tty, |
|---|
| 846 | + struct file *file, struct iov_iter *to) |
|---|
| 847 | +{ |
|---|
| 848 | + int retval = 0; |
|---|
| 849 | + void *cookie = NULL; |
|---|
| 850 | + unsigned long offset = 0; |
|---|
| 851 | + char kernel_buf[64]; |
|---|
| 852 | + size_t count = iov_iter_count(to); |
|---|
| 853 | + |
|---|
| 854 | + do { |
|---|
| 855 | + int size, copied; |
|---|
| 856 | + |
|---|
| 857 | + size = count > sizeof(kernel_buf) ? sizeof(kernel_buf) : count; |
|---|
| 858 | + size = ld->ops->read(tty, file, kernel_buf, size, &cookie, offset); |
|---|
| 859 | + if (!size) |
|---|
| 860 | + break; |
|---|
| 861 | + |
|---|
| 862 | + if (size < 0) { |
|---|
| 863 | + /* Did we have an earlier error (ie -EFAULT)? */ |
|---|
| 864 | + if (retval) |
|---|
| 865 | + break; |
|---|
| 866 | + retval = size; |
|---|
| 867 | + |
|---|
| 868 | + /* |
|---|
| 869 | + * -EOVERFLOW means we didn't have enough space |
|---|
| 870 | + * for a whole packet, and we shouldn't return |
|---|
| 871 | + * a partial result. |
|---|
| 872 | + */ |
|---|
| 873 | + if (retval == -EOVERFLOW) |
|---|
| 874 | + offset = 0; |
|---|
| 875 | + break; |
|---|
| 876 | + } |
|---|
| 877 | + |
|---|
| 878 | + copied = copy_to_iter(kernel_buf, size, to); |
|---|
| 879 | + offset += copied; |
|---|
| 880 | + count -= copied; |
|---|
| 881 | + |
|---|
| 882 | + /* |
|---|
| 883 | + * If the user copy failed, we still need to do another ->read() |
|---|
| 884 | + * call if we had a cookie to let the ldisc clear up. |
|---|
| 885 | + * |
|---|
| 886 | + * But make sure size is zeroed. |
|---|
| 887 | + */ |
|---|
| 888 | + if (unlikely(copied != size)) { |
|---|
| 889 | + count = 0; |
|---|
| 890 | + retval = -EFAULT; |
|---|
| 891 | + } |
|---|
| 892 | + } while (cookie); |
|---|
| 893 | + |
|---|
| 894 | + /* We always clear tty buffer in case they contained passwords */ |
|---|
| 895 | + memzero_explicit(kernel_buf, sizeof(kernel_buf)); |
|---|
| 896 | + return offset ? offset : retval; |
|---|
| 897 | +} |
|---|
| 898 | + |
|---|
| 899 | + |
|---|
| 833 | 900 | /** |
|---|
| 834 | 901 | * tty_read - read method for tty device files |
|---|
| 835 | 902 | * @file: pointer to tty file |
|---|
| .. | .. |
|---|
| 845 | 912 | * read calls may be outstanding in parallel. |
|---|
| 846 | 913 | */ |
|---|
| 847 | 914 | |
|---|
| 848 | | -static ssize_t tty_read(struct file *file, char __user *buf, size_t count, |
|---|
| 849 | | - loff_t *ppos) |
|---|
| 915 | +static ssize_t tty_read(struct kiocb *iocb, struct iov_iter *to) |
|---|
| 850 | 916 | { |
|---|
| 851 | 917 | int i; |
|---|
| 918 | + struct file *file = iocb->ki_filp; |
|---|
| 852 | 919 | struct inode *inode = file_inode(file); |
|---|
| 853 | 920 | struct tty_struct *tty = file_tty(file); |
|---|
| 854 | 921 | struct tty_ldisc *ld; |
|---|
| .. | .. |
|---|
| 862 | 929 | situation */ |
|---|
| 863 | 930 | ld = tty_ldisc_ref_wait(tty); |
|---|
| 864 | 931 | if (!ld) |
|---|
| 865 | | - return hung_up_tty_read(file, buf, count, ppos); |
|---|
| 932 | + return hung_up_tty_read(iocb, to); |
|---|
| 933 | + i = -EIO; |
|---|
| 866 | 934 | if (ld->ops->read) |
|---|
| 867 | | - i = ld->ops->read(tty, file, buf, count); |
|---|
| 868 | | - else |
|---|
| 869 | | - i = -EIO; |
|---|
| 935 | + i = iterate_tty_read(ld, tty, file, to); |
|---|
| 870 | 936 | tty_ldisc_deref(ld); |
|---|
| 871 | 937 | |
|---|
| 872 | 938 | if (i > 0) |
|---|
| .. | .. |
|---|
| 900 | 966 | ssize_t (*write)(struct tty_struct *, struct file *, const unsigned char *, size_t), |
|---|
| 901 | 967 | struct tty_struct *tty, |
|---|
| 902 | 968 | struct file *file, |
|---|
| 903 | | - const char __user *buf, |
|---|
| 904 | | - size_t count) |
|---|
| 969 | + struct iov_iter *from) |
|---|
| 905 | 970 | { |
|---|
| 971 | + size_t count = iov_iter_count(from); |
|---|
| 906 | 972 | ssize_t ret, written = 0; |
|---|
| 907 | 973 | unsigned int chunk; |
|---|
| 908 | 974 | |
|---|
| .. | .. |
|---|
| 954 | 1020 | size_t size = count; |
|---|
| 955 | 1021 | if (size > chunk) |
|---|
| 956 | 1022 | size = chunk; |
|---|
| 1023 | + |
|---|
| 957 | 1024 | ret = -EFAULT; |
|---|
| 958 | | - if (copy_from_user(tty->write_buf, buf, size)) |
|---|
| 1025 | + if (copy_from_iter(tty->write_buf, size, from) != size) |
|---|
| 959 | 1026 | break; |
|---|
| 1027 | + |
|---|
| 960 | 1028 | ret = write(tty, file, tty->write_buf, size); |
|---|
| 961 | 1029 | if (ret <= 0) |
|---|
| 962 | 1030 | break; |
|---|
| 1031 | + |
|---|
| 963 | 1032 | written += ret; |
|---|
| 964 | | - buf += ret; |
|---|
| 1033 | + if (ret > size) |
|---|
| 1034 | + break; |
|---|
| 1035 | + |
|---|
| 1036 | + /* FIXME! Have Al check this! */ |
|---|
| 1037 | + if (ret != size) |
|---|
| 1038 | + iov_iter_revert(from, size-ret); |
|---|
| 1039 | + |
|---|
| 965 | 1040 | count -= ret; |
|---|
| 966 | 1041 | if (!count) |
|---|
| 967 | 1042 | break; |
|---|
| .. | .. |
|---|
| 1021 | 1096 | * write method will not be invoked in parallel for each device. |
|---|
| 1022 | 1097 | */ |
|---|
| 1023 | 1098 | |
|---|
| 1024 | | -static ssize_t tty_write(struct file *file, const char __user *buf, |
|---|
| 1025 | | - size_t count, loff_t *ppos) |
|---|
| 1099 | +static ssize_t file_tty_write(struct file *file, struct kiocb *iocb, struct iov_iter *from) |
|---|
| 1026 | 1100 | { |
|---|
| 1027 | 1101 | struct tty_struct *tty = file_tty(file); |
|---|
| 1028 | 1102 | struct tty_ldisc *ld; |
|---|
| .. | .. |
|---|
| 1037 | 1111 | tty_err(tty, "missing write_room method\n"); |
|---|
| 1038 | 1112 | ld = tty_ldisc_ref_wait(tty); |
|---|
| 1039 | 1113 | if (!ld) |
|---|
| 1040 | | - return hung_up_tty_write(file, buf, count, ppos); |
|---|
| 1114 | + return hung_up_tty_write(iocb, from); |
|---|
| 1041 | 1115 | if (!ld->ops->write) |
|---|
| 1042 | 1116 | ret = -EIO; |
|---|
| 1043 | 1117 | else |
|---|
| 1044 | | - ret = do_tty_write(ld->ops->write, tty, file, buf, count); |
|---|
| 1118 | + ret = do_tty_write(ld->ops->write, tty, file, from); |
|---|
| 1045 | 1119 | tty_ldisc_deref(ld); |
|---|
| 1046 | 1120 | return ret; |
|---|
| 1047 | 1121 | } |
|---|
| 1048 | 1122 | |
|---|
| 1049 | | -ssize_t redirected_tty_write(struct file *file, const char __user *buf, |
|---|
| 1050 | | - size_t count, loff_t *ppos) |
|---|
| 1123 | +static ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from) |
|---|
| 1124 | +{ |
|---|
| 1125 | + return file_tty_write(iocb->ki_filp, iocb, from); |
|---|
| 1126 | +} |
|---|
| 1127 | + |
|---|
| 1128 | +ssize_t redirected_tty_write(struct kiocb *iocb, struct iov_iter *iter) |
|---|
| 1051 | 1129 | { |
|---|
| 1052 | 1130 | struct file *p = NULL; |
|---|
| 1053 | 1131 | |
|---|
| .. | .. |
|---|
| 1056 | 1134 | p = get_file(redirect); |
|---|
| 1057 | 1135 | spin_unlock(&redirect_lock); |
|---|
| 1058 | 1136 | |
|---|
| 1137 | + /* |
|---|
| 1138 | + * We know the redirected tty is just another tty, we can can |
|---|
| 1139 | + * call file_tty_write() directly with that file pointer. |
|---|
| 1140 | + */ |
|---|
| 1059 | 1141 | if (p) { |
|---|
| 1060 | 1142 | ssize_t res; |
|---|
| 1061 | | - res = vfs_write(p, buf, count, &p->f_pos); |
|---|
| 1143 | + res = file_tty_write(p, iocb, iter); |
|---|
| 1062 | 1144 | fput(p); |
|---|
| 1063 | 1145 | return res; |
|---|
| 1064 | 1146 | } |
|---|
| 1065 | | - return tty_write(file, buf, count, ppos); |
|---|
| 1147 | + return tty_write(iocb, iter); |
|---|
| 1066 | 1148 | } |
|---|
| 1067 | 1149 | |
|---|
| 1068 | 1150 | /** |
|---|
| .. | .. |
|---|
| 1172 | 1254 | * tty_init_termios - helper for termios setup |
|---|
| 1173 | 1255 | * @tty: the tty to set up |
|---|
| 1174 | 1256 | * |
|---|
| 1175 | | - * Initialise the termios structures for this tty. Thus runs under |
|---|
| 1257 | + * Initialise the termios structure for this tty. This runs under |
|---|
| 1176 | 1258 | * the tty_mutex currently so we can be relaxed about ordering. |
|---|
| 1177 | 1259 | */ |
|---|
| 1178 | 1260 | |
|---|
| .. | .. |
|---|
| 1230 | 1312 | /** |
|---|
| 1231 | 1313 | * tty_driver_remove_tty() - remove a tty from the driver tables |
|---|
| 1232 | 1314 | * @driver: the driver for the tty |
|---|
| 1233 | | - * @idx: the minor number |
|---|
| 1315 | + * @tty: tty to remove |
|---|
| 1234 | 1316 | * |
|---|
| 1235 | 1317 | * Remvoe a tty object from the driver tables. The tty->index field |
|---|
| 1236 | 1318 | * will be set by the time this is called. |
|---|
| .. | .. |
|---|
| 1245 | 1327 | driver->ttys[tty->index] = NULL; |
|---|
| 1246 | 1328 | } |
|---|
| 1247 | 1329 | |
|---|
| 1248 | | -/* |
|---|
| 1249 | | - * tty_reopen() - fast re-open of an open tty |
|---|
| 1250 | | - * @tty - the tty to open |
|---|
| 1330 | +/** |
|---|
| 1331 | + * tty_reopen() - fast re-open of an open tty |
|---|
| 1332 | + * @tty: the tty to open |
|---|
| 1251 | 1333 | * |
|---|
| 1252 | 1334 | * Return 0 on success, -errno on error. |
|---|
| 1253 | 1335 | * Re-opens on master ptys are not allowed and return -EIO. |
|---|
| .. | .. |
|---|
| 1293 | 1375 | * tty_init_dev - initialise a tty device |
|---|
| 1294 | 1376 | * @driver: tty driver we are opening a device on |
|---|
| 1295 | 1377 | * @idx: device index |
|---|
| 1296 | | - * @ret_tty: returned tty structure |
|---|
| 1297 | 1378 | * |
|---|
| 1298 | 1379 | * Prepare a tty device. This may not be a "new" clean device but |
|---|
| 1299 | 1380 | * could also be an active device. The pty drivers require special |
|---|
| .. | .. |
|---|
| 1311 | 1392 | * failed open. The new code protects the open with a mutex, so it's |
|---|
| 1312 | 1393 | * really quite straightforward. The mutex locking can probably be |
|---|
| 1313 | 1394 | * relaxed for the (most common) case of reopening a tty. |
|---|
| 1395 | + * |
|---|
| 1396 | + * Return: returned tty structure |
|---|
| 1314 | 1397 | */ |
|---|
| 1315 | 1398 | |
|---|
| 1316 | 1399 | struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) |
|---|
| .. | .. |
|---|
| 1343 | 1426 | if (!tty->port) |
|---|
| 1344 | 1427 | tty->port = driver->ports[idx]; |
|---|
| 1345 | 1428 | |
|---|
| 1346 | | - WARN_RATELIMIT(!tty->port, |
|---|
| 1347 | | - "%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n", |
|---|
| 1348 | | - __func__, tty->driver->name); |
|---|
| 1429 | + if (WARN_RATELIMIT(!tty->port, |
|---|
| 1430 | + "%s: %s driver does not set tty->port. This would crash the kernel. Fix the driver!\n", |
|---|
| 1431 | + __func__, tty->driver->name)) { |
|---|
| 1432 | + retval = -EINVAL; |
|---|
| 1433 | + goto err_release_lock; |
|---|
| 1434 | + } |
|---|
| 1349 | 1435 | |
|---|
| 1350 | 1436 | retval = tty_ldisc_lock(tty, 5 * HZ); |
|---|
| 1351 | 1437 | if (retval) |
|---|
| .. | .. |
|---|
| 1400 | 1486 | /* Stash the termios data */ |
|---|
| 1401 | 1487 | tp = tty->driver->termios[idx]; |
|---|
| 1402 | 1488 | if (tp == NULL) { |
|---|
| 1403 | | - tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); |
|---|
| 1489 | + tp = kmalloc(sizeof(*tp), GFP_KERNEL); |
|---|
| 1404 | 1490 | if (tp == NULL) |
|---|
| 1405 | 1491 | return; |
|---|
| 1406 | 1492 | tty->driver->termios[idx] = tp; |
|---|
| .. | .. |
|---|
| 1427 | 1513 | |
|---|
| 1428 | 1514 | /** |
|---|
| 1429 | 1515 | * release_one_tty - release tty structure memory |
|---|
| 1430 | | - * @kref: kref of tty we are obliterating |
|---|
| 1516 | + * @work: work of tty we are obliterating |
|---|
| 1431 | 1517 | * |
|---|
| 1432 | 1518 | * Releases memory associated with a tty structure, and clears out the |
|---|
| 1433 | 1519 | * driver table slots. This function is called when a device is no longer |
|---|
| .. | .. |
|---|
| 1509 | 1595 | tty->ops->shutdown(tty); |
|---|
| 1510 | 1596 | tty_save_termios(tty); |
|---|
| 1511 | 1597 | tty_driver_remove_tty(tty->driver, tty); |
|---|
| 1512 | | - tty->port->itty = NULL; |
|---|
| 1598 | + if (tty->port) |
|---|
| 1599 | + tty->port->itty = NULL; |
|---|
| 1513 | 1600 | if (tty->link) |
|---|
| 1514 | 1601 | tty->link->port->itty = NULL; |
|---|
| 1515 | | - tty_buffer_cancel_work(tty->port); |
|---|
| 1602 | + if (tty->port) |
|---|
| 1603 | + tty_buffer_cancel_work(tty->port); |
|---|
| 1516 | 1604 | if (tty->link) |
|---|
| 1517 | 1605 | tty_buffer_cancel_work(tty->link->port); |
|---|
| 1518 | 1606 | |
|---|
| .. | .. |
|---|
| 1523 | 1611 | /** |
|---|
| 1524 | 1612 | * tty_release_checks - check a tty before real release |
|---|
| 1525 | 1613 | * @tty: tty to check |
|---|
| 1526 | | - * @o_tty: link of @tty (if any) |
|---|
| 1527 | 1614 | * @idx: index of the tty |
|---|
| 1528 | 1615 | * |
|---|
| 1529 | 1616 | * Performs some paranoid checking before true release of the @tty. |
|---|
| .. | .. |
|---|
| 1584 | 1671 | tty_debug_hangup(tty, "freeing structure\n"); |
|---|
| 1585 | 1672 | /* |
|---|
| 1586 | 1673 | * The release_tty function takes care of the details of clearing |
|---|
| 1587 | | - * the slots and preserving the termios structure. The tty_unlock_pair |
|---|
| 1588 | | - * should be safe as we keep a kref while the tty is locked (so the |
|---|
| 1589 | | - * unlock never unlocks a freed tty). |
|---|
| 1674 | + * the slots and preserving the termios structure. |
|---|
| 1590 | 1675 | */ |
|---|
| 1591 | 1676 | mutex_lock(&tty_mutex); |
|---|
| 1592 | 1677 | tty_port_set_kopened(tty->port, 0); |
|---|
| .. | .. |
|---|
| 1616 | 1701 | tty_debug_hangup(tty, "freeing structure\n"); |
|---|
| 1617 | 1702 | /* |
|---|
| 1618 | 1703 | * The release_tty function takes care of the details of clearing |
|---|
| 1619 | | - * the slots and preserving the termios structure. The tty_unlock_pair |
|---|
| 1620 | | - * should be safe as we keep a kref while the tty is locked (so the |
|---|
| 1621 | | - * unlock never unlocks a freed tty). |
|---|
| 1704 | + * the slots and preserving the termios structure. |
|---|
| 1622 | 1705 | */ |
|---|
| 1623 | 1706 | mutex_lock(&tty_mutex); |
|---|
| 1624 | 1707 | release_tty(tty, idx); |
|---|
| .. | .. |
|---|
| 1836 | 1919 | static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, |
|---|
| 1837 | 1920 | int *index) |
|---|
| 1838 | 1921 | { |
|---|
| 1839 | | - struct tty_driver *driver; |
|---|
| 1922 | + struct tty_driver *driver = NULL; |
|---|
| 1840 | 1923 | |
|---|
| 1841 | 1924 | switch (device) { |
|---|
| 1842 | 1925 | #ifdef CONFIG_VT |
|---|
| .. | .. |
|---|
| 1857 | 1940 | break; |
|---|
| 1858 | 1941 | } |
|---|
| 1859 | 1942 | } |
|---|
| 1943 | + if (driver) |
|---|
| 1944 | + tty_driver_kref_put(driver); |
|---|
| 1860 | 1945 | return ERR_PTR(-ENODEV); |
|---|
| 1861 | 1946 | } |
|---|
| 1862 | 1947 | default: |
|---|
| .. | .. |
|---|
| 1886 | 1971 | struct tty_struct *tty_kopen(dev_t device) |
|---|
| 1887 | 1972 | { |
|---|
| 1888 | 1973 | struct tty_struct *tty; |
|---|
| 1889 | | - struct tty_driver *driver = NULL; |
|---|
| 1974 | + struct tty_driver *driver; |
|---|
| 1890 | 1975 | int index = -1; |
|---|
| 1891 | 1976 | |
|---|
| 1892 | 1977 | mutex_lock(&tty_mutex); |
|---|
| .. | .. |
|---|
| 1921 | 2006 | /** |
|---|
| 1922 | 2007 | * tty_open_by_driver - open a tty device |
|---|
| 1923 | 2008 | * @device: dev_t of device to open |
|---|
| 1924 | | - * @inode: inode of device file |
|---|
| 1925 | 2009 | * @filp: file pointer to tty |
|---|
| 1926 | 2010 | * |
|---|
| 1927 | 2011 | * Performs the driver lookup, checks for a reopen, or otherwise |
|---|
| .. | .. |
|---|
| 1934 | 2018 | * - concurrent tty driver removal w/ lookup |
|---|
| 1935 | 2019 | * - concurrent tty removal from driver table |
|---|
| 1936 | 2020 | */ |
|---|
| 1937 | | -static struct tty_struct *tty_open_by_driver(dev_t device, struct inode *inode, |
|---|
| 2021 | +static struct tty_struct *tty_open_by_driver(dev_t device, |
|---|
| 1938 | 2022 | struct file *filp) |
|---|
| 1939 | 2023 | { |
|---|
| 1940 | 2024 | struct tty_struct *tty; |
|---|
| .. | .. |
|---|
| 2026 | 2110 | |
|---|
| 2027 | 2111 | tty = tty_open_current_tty(device, filp); |
|---|
| 2028 | 2112 | if (!tty) |
|---|
| 2029 | | - tty = tty_open_by_driver(device, inode, filp); |
|---|
| 2113 | + tty = tty_open_by_driver(device, filp); |
|---|
| 2030 | 2114 | |
|---|
| 2031 | 2115 | if (IS_ERR(tty)) { |
|---|
| 2032 | 2116 | tty_free_file(filp); |
|---|
| .. | .. |
|---|
| 2198 | 2282 | |
|---|
| 2199 | 2283 | /** |
|---|
| 2200 | 2284 | * tiocgwinsz - implement window query ioctl |
|---|
| 2201 | | - * @tty; tty |
|---|
| 2285 | + * @tty: tty |
|---|
| 2202 | 2286 | * @arg: user buffer for result |
|---|
| 2203 | 2287 | * |
|---|
| 2204 | 2288 | * Copies the kernel idea of the window size into the user buffer. |
|---|
| .. | .. |
|---|
| 2221 | 2305 | /** |
|---|
| 2222 | 2306 | * tty_do_resize - resize event |
|---|
| 2223 | 2307 | * @tty: tty being resized |
|---|
| 2224 | | - * @rows: rows (character) |
|---|
| 2225 | | - * @cols: cols (character) |
|---|
| 2308 | + * @ws: new dimensions |
|---|
| 2226 | 2309 | * |
|---|
| 2227 | 2310 | * Update the termios variables and send the necessary signals to |
|---|
| 2228 | 2311 | * peform a terminal resize correctly |
|---|
| .. | .. |
|---|
| 2252 | 2335 | |
|---|
| 2253 | 2336 | /** |
|---|
| 2254 | 2337 | * tiocswinsz - implement window size set ioctl |
|---|
| 2255 | | - * @tty; tty side of tty |
|---|
| 2338 | + * @tty: tty side of tty |
|---|
| 2256 | 2339 | * @arg: user buffer for result |
|---|
| 2257 | 2340 | * |
|---|
| 2258 | 2341 | * Copies the user idea of the window size to the kernel. Traditionally |
|---|
| .. | .. |
|---|
| 2290 | 2373 | { |
|---|
| 2291 | 2374 | if (!capable(CAP_SYS_ADMIN)) |
|---|
| 2292 | 2375 | return -EPERM; |
|---|
| 2293 | | - if (file->f_op->write == redirected_tty_write) { |
|---|
| 2376 | + if (file->f_op->write_iter == redirected_tty_write) { |
|---|
| 2294 | 2377 | struct file *f; |
|---|
| 2295 | 2378 | spin_lock(&redirect_lock); |
|---|
| 2296 | 2379 | f = redirect; |
|---|
| .. | .. |
|---|
| 2300 | 2383 | fput(f); |
|---|
| 2301 | 2384 | return 0; |
|---|
| 2302 | 2385 | } |
|---|
| 2386 | + if (file->f_op->write_iter != tty_write) |
|---|
| 2387 | + return -ENOTTY; |
|---|
| 2388 | + if (!(file->f_mode & FMODE_WRITE)) |
|---|
| 2389 | + return -EBADF; |
|---|
| 2390 | + if (!(file->f_mode & FMODE_CAN_WRITE)) |
|---|
| 2391 | + return -EINVAL; |
|---|
| 2303 | 2392 | spin_lock(&redirect_lock); |
|---|
| 2304 | 2393 | if (redirect) { |
|---|
| 2305 | 2394 | spin_unlock(&redirect_lock); |
|---|
| .. | .. |
|---|
| 2307 | 2396 | } |
|---|
| 2308 | 2397 | redirect = get_file(file); |
|---|
| 2309 | 2398 | spin_unlock(&redirect_lock); |
|---|
| 2310 | | - return 0; |
|---|
| 2311 | | -} |
|---|
| 2312 | | - |
|---|
| 2313 | | -/** |
|---|
| 2314 | | - * fionbio - non blocking ioctl |
|---|
| 2315 | | - * @file: file to set blocking value |
|---|
| 2316 | | - * @p: user parameter |
|---|
| 2317 | | - * |
|---|
| 2318 | | - * Historical tty interfaces had a blocking control ioctl before |
|---|
| 2319 | | - * the generic functionality existed. This piece of history is preserved |
|---|
| 2320 | | - * in the expected tty API of posix OS's. |
|---|
| 2321 | | - * |
|---|
| 2322 | | - * Locking: none, the open file handle ensures it won't go away. |
|---|
| 2323 | | - */ |
|---|
| 2324 | | - |
|---|
| 2325 | | -static int fionbio(struct file *file, int __user *p) |
|---|
| 2326 | | -{ |
|---|
| 2327 | | - int nonblock; |
|---|
| 2328 | | - |
|---|
| 2329 | | - if (get_user(nonblock, p)) |
|---|
| 2330 | | - return -EFAULT; |
|---|
| 2331 | | - |
|---|
| 2332 | | - spin_lock(&file->f_lock); |
|---|
| 2333 | | - if (nonblock) |
|---|
| 2334 | | - file->f_flags |= O_NONBLOCK; |
|---|
| 2335 | | - else |
|---|
| 2336 | | - file->f_flags &= ~O_NONBLOCK; |
|---|
| 2337 | | - spin_unlock(&file->f_lock); |
|---|
| 2338 | 2399 | return 0; |
|---|
| 2339 | 2400 | } |
|---|
| 2340 | 2401 | |
|---|
| .. | .. |
|---|
| 2428 | 2489 | /** |
|---|
| 2429 | 2490 | * tty_tiocmget - get modem status |
|---|
| 2430 | 2491 | * @tty: tty device |
|---|
| 2431 | | - * @file: user file pointer |
|---|
| 2432 | 2492 | * @p: pointer to result |
|---|
| 2433 | 2493 | * |
|---|
| 2434 | 2494 | * Obtain the modem status bits from the tty driver if the feature |
|---|
| .. | .. |
|---|
| 2506 | 2566 | return 0; |
|---|
| 2507 | 2567 | } |
|---|
| 2508 | 2568 | |
|---|
| 2509 | | -static void tty_warn_deprecated_flags(struct serial_struct __user *ss) |
|---|
| 2569 | +static int tty_tiocsserial(struct tty_struct *tty, struct serial_struct __user *ss) |
|---|
| 2510 | 2570 | { |
|---|
| 2511 | 2571 | static DEFINE_RATELIMIT_STATE(depr_flags, |
|---|
| 2512 | 2572 | DEFAULT_RATELIMIT_INTERVAL, |
|---|
| 2513 | 2573 | DEFAULT_RATELIMIT_BURST); |
|---|
| 2514 | 2574 | char comm[TASK_COMM_LEN]; |
|---|
| 2575 | + struct serial_struct v; |
|---|
| 2515 | 2576 | int flags; |
|---|
| 2516 | 2577 | |
|---|
| 2517 | | - if (get_user(flags, &ss->flags)) |
|---|
| 2518 | | - return; |
|---|
| 2578 | + if (copy_from_user(&v, ss, sizeof(*ss))) |
|---|
| 2579 | + return -EFAULT; |
|---|
| 2519 | 2580 | |
|---|
| 2520 | | - flags &= ASYNC_DEPRECATED; |
|---|
| 2581 | + flags = v.flags & ASYNC_DEPRECATED; |
|---|
| 2521 | 2582 | |
|---|
| 2522 | 2583 | if (flags && __ratelimit(&depr_flags)) |
|---|
| 2523 | 2584 | pr_warn("%s: '%s' is using deprecated serial flags (with no effect): %.8x\n", |
|---|
| 2524 | 2585 | __func__, get_task_comm(comm, current), flags); |
|---|
| 2586 | + if (!tty->ops->set_serial) |
|---|
| 2587 | + return -ENOTTY; |
|---|
| 2588 | + return tty->ops->set_serial(tty, &v); |
|---|
| 2589 | +} |
|---|
| 2590 | + |
|---|
| 2591 | +static int tty_tiocgserial(struct tty_struct *tty, struct serial_struct __user *ss) |
|---|
| 2592 | +{ |
|---|
| 2593 | + struct serial_struct v; |
|---|
| 2594 | + int err; |
|---|
| 2595 | + |
|---|
| 2596 | + memset(&v, 0, sizeof(v)); |
|---|
| 2597 | + if (!tty->ops->get_serial) |
|---|
| 2598 | + return -ENOTTY; |
|---|
| 2599 | + err = tty->ops->get_serial(tty, &v); |
|---|
| 2600 | + if (!err && copy_to_user(ss, &v, sizeof(v))) |
|---|
| 2601 | + err = -EFAULT; |
|---|
| 2602 | + return err; |
|---|
| 2525 | 2603 | } |
|---|
| 2526 | 2604 | |
|---|
| 2527 | 2605 | /* |
|---|
| .. | .. |
|---|
| 2584 | 2662 | return tiocswinsz(real_tty, p); |
|---|
| 2585 | 2663 | case TIOCCONS: |
|---|
| 2586 | 2664 | return real_tty != tty ? -EINVAL : tioccons(file); |
|---|
| 2587 | | - case FIONBIO: |
|---|
| 2588 | | - return fionbio(file, p); |
|---|
| 2589 | 2665 | case TIOCEXCL: |
|---|
| 2590 | 2666 | set_bit(TTY_EXCLUSIVE, &tty->flags); |
|---|
| 2591 | 2667 | return 0; |
|---|
| .. | .. |
|---|
| 2640 | 2716 | case TIOCMBIS: |
|---|
| 2641 | 2717 | return tty_tiocmset(tty, cmd, p); |
|---|
| 2642 | 2718 | case TIOCGICOUNT: |
|---|
| 2643 | | - retval = tty_tiocgicount(tty, p); |
|---|
| 2644 | | - /* For the moment allow fall through to the old method */ |
|---|
| 2645 | | - if (retval != -EINVAL) |
|---|
| 2646 | | - return retval; |
|---|
| 2647 | | - break; |
|---|
| 2719 | + return tty_tiocgicount(tty, p); |
|---|
| 2648 | 2720 | case TCFLSH: |
|---|
| 2649 | 2721 | switch (arg) { |
|---|
| 2650 | 2722 | case TCIFLUSH: |
|---|
| .. | .. |
|---|
| 2655 | 2727 | } |
|---|
| 2656 | 2728 | break; |
|---|
| 2657 | 2729 | case TIOCSSERIAL: |
|---|
| 2658 | | - tty_warn_deprecated_flags(p); |
|---|
| 2659 | | - break; |
|---|
| 2730 | + return tty_tiocsserial(tty, p); |
|---|
| 2731 | + case TIOCGSERIAL: |
|---|
| 2732 | + return tty_tiocgserial(tty, p); |
|---|
| 2660 | 2733 | case TIOCGPTPEER: |
|---|
| 2661 | 2734 | /* Special because the struct file is needed */ |
|---|
| 2662 | 2735 | return ptm_open_peer(file, tty, (int)arg); |
|---|
| .. | .. |
|---|
| 2684 | 2757 | } |
|---|
| 2685 | 2758 | |
|---|
| 2686 | 2759 | #ifdef CONFIG_COMPAT |
|---|
| 2760 | + |
|---|
| 2761 | +struct serial_struct32 { |
|---|
| 2762 | + compat_int_t type; |
|---|
| 2763 | + compat_int_t line; |
|---|
| 2764 | + compat_uint_t port; |
|---|
| 2765 | + compat_int_t irq; |
|---|
| 2766 | + compat_int_t flags; |
|---|
| 2767 | + compat_int_t xmit_fifo_size; |
|---|
| 2768 | + compat_int_t custom_divisor; |
|---|
| 2769 | + compat_int_t baud_base; |
|---|
| 2770 | + unsigned short close_delay; |
|---|
| 2771 | + char io_type; |
|---|
| 2772 | + char reserved_char; |
|---|
| 2773 | + compat_int_t hub6; |
|---|
| 2774 | + unsigned short closing_wait; /* time to wait before closing */ |
|---|
| 2775 | + unsigned short closing_wait2; /* no longer used... */ |
|---|
| 2776 | + compat_uint_t iomem_base; |
|---|
| 2777 | + unsigned short iomem_reg_shift; |
|---|
| 2778 | + unsigned int port_high; |
|---|
| 2779 | + /* compat_ulong_t iomap_base FIXME */ |
|---|
| 2780 | + compat_int_t reserved; |
|---|
| 2781 | +}; |
|---|
| 2782 | + |
|---|
| 2783 | +static int compat_tty_tiocsserial(struct tty_struct *tty, |
|---|
| 2784 | + struct serial_struct32 __user *ss) |
|---|
| 2785 | +{ |
|---|
| 2786 | + static DEFINE_RATELIMIT_STATE(depr_flags, |
|---|
| 2787 | + DEFAULT_RATELIMIT_INTERVAL, |
|---|
| 2788 | + DEFAULT_RATELIMIT_BURST); |
|---|
| 2789 | + char comm[TASK_COMM_LEN]; |
|---|
| 2790 | + struct serial_struct32 v32; |
|---|
| 2791 | + struct serial_struct v; |
|---|
| 2792 | + int flags; |
|---|
| 2793 | + |
|---|
| 2794 | + if (copy_from_user(&v32, ss, sizeof(*ss))) |
|---|
| 2795 | + return -EFAULT; |
|---|
| 2796 | + |
|---|
| 2797 | + memcpy(&v, &v32, offsetof(struct serial_struct32, iomem_base)); |
|---|
| 2798 | + v.iomem_base = compat_ptr(v32.iomem_base); |
|---|
| 2799 | + v.iomem_reg_shift = v32.iomem_reg_shift; |
|---|
| 2800 | + v.port_high = v32.port_high; |
|---|
| 2801 | + v.iomap_base = 0; |
|---|
| 2802 | + |
|---|
| 2803 | + flags = v.flags & ASYNC_DEPRECATED; |
|---|
| 2804 | + |
|---|
| 2805 | + if (flags && __ratelimit(&depr_flags)) |
|---|
| 2806 | + pr_warn("%s: '%s' is using deprecated serial flags (with no effect): %.8x\n", |
|---|
| 2807 | + __func__, get_task_comm(comm, current), flags); |
|---|
| 2808 | + if (!tty->ops->set_serial) |
|---|
| 2809 | + return -ENOTTY; |
|---|
| 2810 | + return tty->ops->set_serial(tty, &v); |
|---|
| 2811 | +} |
|---|
| 2812 | + |
|---|
| 2813 | +static int compat_tty_tiocgserial(struct tty_struct *tty, |
|---|
| 2814 | + struct serial_struct32 __user *ss) |
|---|
| 2815 | +{ |
|---|
| 2816 | + struct serial_struct32 v32; |
|---|
| 2817 | + struct serial_struct v; |
|---|
| 2818 | + int err; |
|---|
| 2819 | + |
|---|
| 2820 | + memset(&v, 0, sizeof(v)); |
|---|
| 2821 | + memset(&v32, 0, sizeof(v32)); |
|---|
| 2822 | + |
|---|
| 2823 | + if (!tty->ops->get_serial) |
|---|
| 2824 | + return -ENOTTY; |
|---|
| 2825 | + err = tty->ops->get_serial(tty, &v); |
|---|
| 2826 | + if (!err) { |
|---|
| 2827 | + memcpy(&v32, &v, offsetof(struct serial_struct32, iomem_base)); |
|---|
| 2828 | + v32.iomem_base = (unsigned long)v.iomem_base >> 32 ? |
|---|
| 2829 | + 0xfffffff : ptr_to_compat(v.iomem_base); |
|---|
| 2830 | + v32.iomem_reg_shift = v.iomem_reg_shift; |
|---|
| 2831 | + v32.port_high = v.port_high; |
|---|
| 2832 | + if (copy_to_user(ss, &v32, sizeof(v32))) |
|---|
| 2833 | + err = -EFAULT; |
|---|
| 2834 | + } |
|---|
| 2835 | + return err; |
|---|
| 2836 | +} |
|---|
| 2687 | 2837 | static long tty_compat_ioctl(struct file *file, unsigned int cmd, |
|---|
| 2688 | 2838 | unsigned long arg) |
|---|
| 2689 | 2839 | { |
|---|
| .. | .. |
|---|
| 2691 | 2841 | struct tty_ldisc *ld; |
|---|
| 2692 | 2842 | int retval = -ENOIOCTLCMD; |
|---|
| 2693 | 2843 | |
|---|
| 2844 | + switch (cmd) { |
|---|
| 2845 | + case TIOCOUTQ: |
|---|
| 2846 | + case TIOCSTI: |
|---|
| 2847 | + case TIOCGWINSZ: |
|---|
| 2848 | + case TIOCSWINSZ: |
|---|
| 2849 | + case TIOCGEXCL: |
|---|
| 2850 | + case TIOCGETD: |
|---|
| 2851 | + case TIOCSETD: |
|---|
| 2852 | + case TIOCGDEV: |
|---|
| 2853 | + case TIOCMGET: |
|---|
| 2854 | + case TIOCMSET: |
|---|
| 2855 | + case TIOCMBIC: |
|---|
| 2856 | + case TIOCMBIS: |
|---|
| 2857 | + case TIOCGICOUNT: |
|---|
| 2858 | + case TIOCGPGRP: |
|---|
| 2859 | + case TIOCSPGRP: |
|---|
| 2860 | + case TIOCGSID: |
|---|
| 2861 | + case TIOCSERGETLSR: |
|---|
| 2862 | + case TIOCGRS485: |
|---|
| 2863 | + case TIOCSRS485: |
|---|
| 2864 | +#ifdef TIOCGETP |
|---|
| 2865 | + case TIOCGETP: |
|---|
| 2866 | + case TIOCSETP: |
|---|
| 2867 | + case TIOCSETN: |
|---|
| 2868 | +#endif |
|---|
| 2869 | +#ifdef TIOCGETC |
|---|
| 2870 | + case TIOCGETC: |
|---|
| 2871 | + case TIOCSETC: |
|---|
| 2872 | +#endif |
|---|
| 2873 | +#ifdef TIOCGLTC |
|---|
| 2874 | + case TIOCGLTC: |
|---|
| 2875 | + case TIOCSLTC: |
|---|
| 2876 | +#endif |
|---|
| 2877 | + case TCSETSF: |
|---|
| 2878 | + case TCSETSW: |
|---|
| 2879 | + case TCSETS: |
|---|
| 2880 | + case TCGETS: |
|---|
| 2881 | +#ifdef TCGETS2 |
|---|
| 2882 | + case TCGETS2: |
|---|
| 2883 | + case TCSETSF2: |
|---|
| 2884 | + case TCSETSW2: |
|---|
| 2885 | + case TCSETS2: |
|---|
| 2886 | +#endif |
|---|
| 2887 | + case TCGETA: |
|---|
| 2888 | + case TCSETAF: |
|---|
| 2889 | + case TCSETAW: |
|---|
| 2890 | + case TCSETA: |
|---|
| 2891 | + case TIOCGLCKTRMIOS: |
|---|
| 2892 | + case TIOCSLCKTRMIOS: |
|---|
| 2893 | +#ifdef TCGETX |
|---|
| 2894 | + case TCGETX: |
|---|
| 2895 | + case TCSETX: |
|---|
| 2896 | + case TCSETXW: |
|---|
| 2897 | + case TCSETXF: |
|---|
| 2898 | +#endif |
|---|
| 2899 | + case TIOCGSOFTCAR: |
|---|
| 2900 | + case TIOCSSOFTCAR: |
|---|
| 2901 | + |
|---|
| 2902 | + case PPPIOCGCHAN: |
|---|
| 2903 | + case PPPIOCGUNIT: |
|---|
| 2904 | + return tty_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); |
|---|
| 2905 | + case TIOCCONS: |
|---|
| 2906 | + case TIOCEXCL: |
|---|
| 2907 | + case TIOCNXCL: |
|---|
| 2908 | + case TIOCVHANGUP: |
|---|
| 2909 | + case TIOCSBRK: |
|---|
| 2910 | + case TIOCCBRK: |
|---|
| 2911 | + case TCSBRK: |
|---|
| 2912 | + case TCSBRKP: |
|---|
| 2913 | + case TCFLSH: |
|---|
| 2914 | + case TIOCGPTPEER: |
|---|
| 2915 | + case TIOCNOTTY: |
|---|
| 2916 | + case TIOCSCTTY: |
|---|
| 2917 | + case TCXONC: |
|---|
| 2918 | + case TIOCMIWAIT: |
|---|
| 2919 | + case TIOCSERCONFIG: |
|---|
| 2920 | + return tty_ioctl(file, cmd, arg); |
|---|
| 2921 | + } |
|---|
| 2922 | + |
|---|
| 2694 | 2923 | if (tty_paranoia_check(tty, file_inode(file), "tty_ioctl")) |
|---|
| 2695 | 2924 | return -EINVAL; |
|---|
| 2696 | 2925 | |
|---|
| 2926 | + switch (cmd) { |
|---|
| 2927 | + case TIOCSSERIAL: |
|---|
| 2928 | + return compat_tty_tiocsserial(tty, compat_ptr(arg)); |
|---|
| 2929 | + case TIOCGSERIAL: |
|---|
| 2930 | + return compat_tty_tiocgserial(tty, compat_ptr(arg)); |
|---|
| 2931 | + } |
|---|
| 2697 | 2932 | if (tty->ops->compat_ioctl) { |
|---|
| 2698 | 2933 | retval = tty->ops->compat_ioctl(tty, cmd, arg); |
|---|
| 2699 | 2934 | if (retval != -ENOIOCTLCMD) |
|---|
| .. | .. |
|---|
| 2705 | 2940 | return hung_up_tty_compat_ioctl(file, cmd, arg); |
|---|
| 2706 | 2941 | if (ld->ops->compat_ioctl) |
|---|
| 2707 | 2942 | retval = ld->ops->compat_ioctl(tty, file, cmd, arg); |
|---|
| 2708 | | - else |
|---|
| 2709 | | - retval = n_tty_compat_ioctl_helper(tty, file, cmd, arg); |
|---|
| 2943 | + if (retval == -ENOIOCTLCMD && ld->ops->ioctl) |
|---|
| 2944 | + retval = ld->ops->ioctl(tty, file, |
|---|
| 2945 | + (unsigned long)compat_ptr(cmd), arg); |
|---|
| 2710 | 2946 | tty_ldisc_deref(ld); |
|---|
| 2711 | 2947 | |
|---|
| 2712 | 2948 | return retval; |
|---|
| .. | .. |
|---|
| 2715 | 2951 | |
|---|
| 2716 | 2952 | static int this_tty(const void *t, struct file *file, unsigned fd) |
|---|
| 2717 | 2953 | { |
|---|
| 2718 | | - if (likely(file->f_op->read != tty_read)) |
|---|
| 2954 | + if (likely(file->f_op->read_iter != tty_read)) |
|---|
| 2719 | 2955 | return 0; |
|---|
| 2720 | 2956 | return file_tty(file) != t ? 0 : fd + 1; |
|---|
| 2721 | 2957 | } |
|---|
| .. | .. |
|---|
| 2765 | 3001 | do_each_pid_task(session, PIDTYPE_SID, p) { |
|---|
| 2766 | 3002 | tty_notice(tty, "SAK: killed process %d (%s): by session\n", |
|---|
| 2767 | 3003 | task_pid_nr(p), p->comm); |
|---|
| 2768 | | - send_sig(SIGKILL, p, 1); |
|---|
| 3004 | + group_send_sig_info(SIGKILL, SEND_SIG_PRIV, p, PIDTYPE_SID); |
|---|
| 2769 | 3005 | } while_each_pid_task(session, PIDTYPE_SID, p); |
|---|
| 2770 | 3006 | |
|---|
| 2771 | 3007 | /* Now kill any processes that happen to have the tty open */ |
|---|
| .. | .. |
|---|
| 2773 | 3009 | if (p->signal->tty == tty) { |
|---|
| 2774 | 3010 | tty_notice(tty, "SAK: killed process %d (%s): by controlling tty\n", |
|---|
| 2775 | 3011 | task_pid_nr(p), p->comm); |
|---|
| 2776 | | - send_sig(SIGKILL, p, 1); |
|---|
| 3012 | + group_send_sig_info(SIGKILL, SEND_SIG_PRIV, p, PIDTYPE_SID); |
|---|
| 2777 | 3013 | continue; |
|---|
| 2778 | 3014 | } |
|---|
| 2779 | 3015 | task_lock(p); |
|---|
| .. | .. |
|---|
| 2781 | 3017 | if (i != 0) { |
|---|
| 2782 | 3018 | tty_notice(tty, "SAK: killed process %d (%s): by fd#%d\n", |
|---|
| 2783 | 3019 | task_pid_nr(p), p->comm, i - 1); |
|---|
| 2784 | | - force_sig(SIGKILL, p); |
|---|
| 3020 | + group_send_sig_info(SIGKILL, SEND_SIG_PRIV, p, PIDTYPE_SID); |
|---|
| 2785 | 3021 | } |
|---|
| 2786 | 3022 | task_unlock(p); |
|---|
| 2787 | 3023 | } while_each_thread(g, p); |
|---|
| .. | .. |
|---|
| 2812 | 3048 | |
|---|
| 2813 | 3049 | EXPORT_SYMBOL(do_SAK); |
|---|
| 2814 | 3050 | |
|---|
| 2815 | | -static int dev_match_devt(struct device *dev, const void *data) |
|---|
| 2816 | | -{ |
|---|
| 2817 | | - const dev_t *devt = data; |
|---|
| 2818 | | - return dev->devt == *devt; |
|---|
| 2819 | | -} |
|---|
| 2820 | | - |
|---|
| 2821 | 3051 | /* Must put_device() after it's unused! */ |
|---|
| 2822 | 3052 | static struct device *tty_get_device(struct tty_struct *tty) |
|---|
| 2823 | 3053 | { |
|---|
| 2824 | 3054 | dev_t devt = tty_devnum(tty); |
|---|
| 2825 | | - return class_find_device(tty_class, NULL, &devt, dev_match_devt); |
|---|
| 3055 | + return class_find_device_by_devt(tty_class, devt); |
|---|
| 2826 | 3056 | } |
|---|
| 2827 | 3057 | |
|---|
| 2828 | 3058 | |
|---|
| .. | .. |
|---|
| 3076 | 3306 | if (!lines || (flags & TTY_DRIVER_UNNUMBERED_NODE && lines > 1)) |
|---|
| 3077 | 3307 | return ERR_PTR(-EINVAL); |
|---|
| 3078 | 3308 | |
|---|
| 3079 | | - driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); |
|---|
| 3309 | + driver = kzalloc(sizeof(*driver), GFP_KERNEL); |
|---|
| 3080 | 3310 | if (!driver) |
|---|
| 3081 | 3311 | return ERR_PTR(-ENOMEM); |
|---|
| 3082 | 3312 | |
|---|