| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright 2008 Red Hat, Inc. All rights reserved. |
|---|
| 3 | 4 | * Copyright 2008 Ian Kent <raven@themaw.net> |
|---|
| 4 | | - * |
|---|
| 5 | | - * This file is part of the Linux kernel and is made available under |
|---|
| 6 | | - * the terms of the GNU General Public License, version 2, or at your |
|---|
| 7 | | - * option, any later version, incorporated herein by reference. |
|---|
| 8 | 5 | */ |
|---|
| 9 | 6 | |
|---|
| 10 | 7 | #include <linux/miscdevice.h> |
|---|
| 11 | 8 | #include <linux/compat.h> |
|---|
| 12 | 9 | #include <linux/syscalls.h> |
|---|
| 13 | 10 | #include <linux/magic.h> |
|---|
| 11 | +#include <linux/nospec.h> |
|---|
| 14 | 12 | |
|---|
| 15 | 13 | #include "autofs_i.h" |
|---|
| 16 | 14 | |
|---|
| .. | .. |
|---|
| 23 | 21 | * another mount. This situation arises when starting automount(8) |
|---|
| 24 | 22 | * or other user space daemon which uses direct mounts or offset |
|---|
| 25 | 23 | * mounts (used for autofs lazy mount/umount of nested mount trees), |
|---|
| 26 | | - * which have been left busy at at service shutdown. |
|---|
| 24 | + * which have been left busy at service shutdown. |
|---|
| 27 | 25 | */ |
|---|
| 28 | 26 | |
|---|
| 29 | 27 | typedef int (*ioctl_fn)(struct file *, struct autofs_sb_info *, |
|---|
| .. | .. |
|---|
| 151 | 149 | return err; |
|---|
| 152 | 150 | } |
|---|
| 153 | 151 | |
|---|
| 154 | | -/* |
|---|
| 155 | | - * Get the autofs super block info struct from the file opened on |
|---|
| 156 | | - * the autofs mount point. |
|---|
| 157 | | - */ |
|---|
| 158 | | -static struct autofs_sb_info *autofs_dev_ioctl_sbi(struct file *f) |
|---|
| 159 | | -{ |
|---|
| 160 | | - struct autofs_sb_info *sbi = NULL; |
|---|
| 161 | | - struct inode *inode; |
|---|
| 162 | | - |
|---|
| 163 | | - if (f) { |
|---|
| 164 | | - inode = file_inode(f); |
|---|
| 165 | | - sbi = autofs_sbi(inode->i_sb); |
|---|
| 166 | | - } |
|---|
| 167 | | - return sbi; |
|---|
| 168 | | -} |
|---|
| 169 | | - |
|---|
| 170 | 152 | /* Return autofs dev ioctl version */ |
|---|
| 171 | 153 | static int autofs_dev_ioctl_version(struct file *fp, |
|---|
| 172 | 154 | struct autofs_sb_info *sbi, |
|---|
| .. | .. |
|---|
| 205 | 187 | struct path path; |
|---|
| 206 | 188 | int err; |
|---|
| 207 | 189 | |
|---|
| 208 | | - err = kern_path_mountpoint(AT_FDCWD, pathname, &path, 0); |
|---|
| 190 | + err = kern_path(pathname, LOOKUP_MOUNTPOINT, &path); |
|---|
| 209 | 191 | if (err) |
|---|
| 210 | 192 | return err; |
|---|
| 211 | 193 | err = -ENOENT; |
|---|
| .. | .. |
|---|
| 366 | 348 | pipefd = param->setpipefd.pipefd; |
|---|
| 367 | 349 | |
|---|
| 368 | 350 | mutex_lock(&sbi->wq_mutex); |
|---|
| 369 | | - if (!sbi->catatonic) { |
|---|
| 351 | + if (!(sbi->flags & AUTOFS_SBI_CATATONIC)) { |
|---|
| 370 | 352 | mutex_unlock(&sbi->wq_mutex); |
|---|
| 371 | 353 | return -EBUSY; |
|---|
| 372 | 354 | } else { |
|---|
| .. | .. |
|---|
| 393 | 375 | swap(sbi->oz_pgrp, new_pid); |
|---|
| 394 | 376 | sbi->pipefd = pipefd; |
|---|
| 395 | 377 | sbi->pipe = pipe; |
|---|
| 396 | | - sbi->catatonic = 0; |
|---|
| 378 | + sbi->flags &= ~AUTOFS_SBI_CATATONIC; |
|---|
| 397 | 379 | } |
|---|
| 398 | 380 | out: |
|---|
| 399 | 381 | put_pid(new_pid); |
|---|
| .. | .. |
|---|
| 515 | 497 | * located path is the root of a mount we return 1 along with |
|---|
| 516 | 498 | * the super magic of the mount or 0 otherwise. |
|---|
| 517 | 499 | * |
|---|
| 518 | | - * In both cases the the device number (as returned by |
|---|
| 500 | + * In both cases the device number (as returned by |
|---|
| 519 | 501 | * new_encode_dev()) is also returned. |
|---|
| 520 | 502 | */ |
|---|
| 521 | 503 | static int autofs_dev_ioctl_ismountpoint(struct file *fp, |
|---|
| .. | .. |
|---|
| 538 | 520 | |
|---|
| 539 | 521 | if (!fp || param->ioctlfd == -1) { |
|---|
| 540 | 522 | if (autofs_type_any(type)) |
|---|
| 541 | | - err = kern_path_mountpoint(AT_FDCWD, |
|---|
| 542 | | - name, &path, LOOKUP_FOLLOW); |
|---|
| 523 | + err = kern_path(name, LOOKUP_FOLLOW | LOOKUP_MOUNTPOINT, |
|---|
| 524 | + &path); |
|---|
| 543 | 525 | else |
|---|
| 544 | 526 | err = find_autofs_mount(name, &path, |
|---|
| 545 | 527 | test_by_type, &type); |
|---|
| .. | .. |
|---|
| 582 | 564 | |
|---|
| 583 | 565 | static ioctl_fn lookup_dev_ioctl(unsigned int cmd) |
|---|
| 584 | 566 | { |
|---|
| 585 | | - static ioctl_fn _ioctls[] = { |
|---|
| 567 | + static const ioctl_fn _ioctls[] = { |
|---|
| 586 | 568 | autofs_dev_ioctl_version, |
|---|
| 587 | 569 | autofs_dev_ioctl_protover, |
|---|
| 588 | 570 | autofs_dev_ioctl_protosubver, |
|---|
| .. | .. |
|---|
| 600 | 582 | }; |
|---|
| 601 | 583 | unsigned int idx = cmd_idx(cmd); |
|---|
| 602 | 584 | |
|---|
| 603 | | - return (idx >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[idx]; |
|---|
| 585 | + if (idx >= ARRAY_SIZE(_ioctls)) |
|---|
| 586 | + return NULL; |
|---|
| 587 | + idx = array_index_nospec(idx, ARRAY_SIZE(_ioctls)); |
|---|
| 588 | + return _ioctls[idx]; |
|---|
| 604 | 589 | } |
|---|
| 605 | 590 | |
|---|
| 606 | 591 | /* ioctl dispatcher */ |
|---|
| .. | .. |
|---|
| 658 | 643 | if (cmd != AUTOFS_DEV_IOCTL_VERSION_CMD && |
|---|
| 659 | 644 | cmd != AUTOFS_DEV_IOCTL_OPENMOUNT_CMD && |
|---|
| 660 | 645 | cmd != AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD) { |
|---|
| 646 | + struct super_block *sb; |
|---|
| 647 | + |
|---|
| 661 | 648 | fp = fget(param->ioctlfd); |
|---|
| 662 | 649 | if (!fp) { |
|---|
| 663 | 650 | if (cmd == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD) |
|---|
| .. | .. |
|---|
| 666 | 653 | goto out; |
|---|
| 667 | 654 | } |
|---|
| 668 | 655 | |
|---|
| 669 | | - sbi = autofs_dev_ioctl_sbi(fp); |
|---|
| 670 | | - if (!sbi || sbi->magic != AUTOFS_SBI_MAGIC) { |
|---|
| 656 | + sb = file_inode(fp)->i_sb; |
|---|
| 657 | + if (sb->s_type != &autofs_fs_type) { |
|---|
| 671 | 658 | err = -EINVAL; |
|---|
| 672 | 659 | fput(fp); |
|---|
| 673 | 660 | goto out; |
|---|
| 674 | 661 | } |
|---|
| 662 | + sbi = autofs_sbi(sb); |
|---|
| 675 | 663 | |
|---|
| 676 | 664 | /* |
|---|
| 677 | 665 | * Admin needs to be able to set the mount catatonic in |
|---|