.. | .. |
---|
| 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 |
---|