summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Kent <raven@themaw.net>2018-08-22 00:58:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-22 13:52:49 -0400
commitd4d79b8195bfc6d5d8f82f9189c1bc828cc7e03a (patch)
tree48072d7daf0eaa2e244d6ecf08771c9e72fa62e1
parent3f5c15d8a7d86fb642fe07df58c2065190f3e531 (diff)
autofs: fix directory and symlink access
Depending on how it is configured the autofs user space daemon can leave in use mounts mounted at exit and re-connect to them at start up. But for this to work best the state of the autofs file system needs to be left intact over the restart. Also, at system shutdown, mounts in an autofs file system might be umounted exposing a mount point trigger for which subsequent access can lead to a hang. So recent versions of automount(8) now does its best to set autofs file system mounts catatonic at shutdown. When autofs file system mounts are catatonic it's currently possible to create and remove directories and symlinks which can be a problem at restart, as described above. So return EACCES in the directory, symlink and unlink methods if the autofs file system is catatonic. Link: http://lkml.kernel.org/r/152902119090.4144.9561910674530214291.stgit@pluto.themaw.net Signed-off-by: Ian Kent <raven@themaw.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/autofs/root.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/fs/autofs/root.c b/fs/autofs/root.c
index a3d414150578..782e57b911ab 100644
--- a/fs/autofs/root.c
+++ b/fs/autofs/root.c
@@ -559,6 +559,13 @@ static int autofs_dir_symlink(struct inode *dir,
559 if (!autofs_oz_mode(sbi)) 559 if (!autofs_oz_mode(sbi))
560 return -EACCES; 560 return -EACCES;
561 561
562 /* autofs_oz_mode() needs to allow path walks when the
563 * autofs mount is catatonic but the state of an autofs
564 * file system needs to be preserved over restarts.
565 */
566 if (sbi->catatonic)
567 return -EACCES;
568
562 BUG_ON(!ino); 569 BUG_ON(!ino);
563 570
564 autofs_clean_ino(ino); 571 autofs_clean_ino(ino);
@@ -612,9 +619,15 @@ static int autofs_dir_unlink(struct inode *dir, struct dentry *dentry)
612 struct autofs_info *ino = autofs_dentry_ino(dentry); 619 struct autofs_info *ino = autofs_dentry_ino(dentry);
613 struct autofs_info *p_ino; 620 struct autofs_info *p_ino;
614 621
615 /* This allows root to remove symlinks */ 622 if (!autofs_oz_mode(sbi))
616 if (!autofs_oz_mode(sbi) && !capable(CAP_SYS_ADMIN)) 623 return -EACCES;
617 return -EPERM; 624
625 /* autofs_oz_mode() needs to allow path walks when the
626 * autofs mount is catatonic but the state of an autofs
627 * file system needs to be preserved over restarts.
628 */
629 if (sbi->catatonic)
630 return -EACCES;
618 631
619 if (atomic_dec_and_test(&ino->count)) { 632 if (atomic_dec_and_test(&ino->count)) {
620 p_ino = autofs_dentry_ino(dentry->d_parent); 633 p_ino = autofs_dentry_ino(dentry->d_parent);
@@ -697,6 +710,13 @@ static int autofs_dir_rmdir(struct inode *dir, struct dentry *dentry)
697 if (!autofs_oz_mode(sbi)) 710 if (!autofs_oz_mode(sbi))
698 return -EACCES; 711 return -EACCES;
699 712
713 /* autofs_oz_mode() needs to allow path walks when the
714 * autofs mount is catatonic but the state of an autofs
715 * file system needs to be preserved over restarts.
716 */
717 if (sbi->catatonic)
718 return -EACCES;
719
700 spin_lock(&sbi->lookup_lock); 720 spin_lock(&sbi->lookup_lock);
701 if (!simple_empty(dentry)) { 721 if (!simple_empty(dentry)) {
702 spin_unlock(&sbi->lookup_lock); 722 spin_unlock(&sbi->lookup_lock);
@@ -735,6 +755,13 @@ static int autofs_dir_mkdir(struct inode *dir,
735 if (!autofs_oz_mode(sbi)) 755 if (!autofs_oz_mode(sbi))
736 return -EACCES; 756 return -EACCES;
737 757
758 /* autofs_oz_mode() needs to allow path walks when the
759 * autofs mount is catatonic but the state of an autofs
760 * file system needs to be preserved over restarts.
761 */
762 if (sbi->catatonic)
763 return -EACCES;
764
738 pr_debug("dentry %p, creating %pd\n", dentry, dentry); 765 pr_debug("dentry %p, creating %pd\n", dentry, dentry);
739 766
740 BUG_ON(!ino); 767 BUG_ON(!ino);