[PATCH] libselinux: selinux_restorecon: avoid triggering auto-mounts unnecessarily

Stephen Smalley <[email protected]> Wed, 29 Jul 2026 09:12:03 -0400
Newsgroups org.kernel.vger.selinux
Message-ID <[email protected]>
Félix-Antoine Fortin <[email protected]> reported
the following bug report, quoted verbatim:
---<snip>---
I encountered an unexpected side effect in restorecon: processing a
single local file triggers unrelated automounts.

Command (called during ipa-client-install):

  $ restorecon /etc/krb5.conf.d/freeipa

Although the target is under /etc, this causes all of the following
NFS automounts to activate:

  nfs-home.automount
  nfs-project.automount
  nfs-scratch.automount

The journal identifies restorecon as the process that triggered each automount:

  systemd[1]: nfs-home.automount: Got automount request for /nfs/home,
triggered by 10521 (restorecon)
  systemd[1]: Mounting /nfs/home...
  nfsrahead[10530]: setting /nfs/home readahead to 128
  systemd[1]: Mounted /nfs/home.
  systemd[1]: nfs-project.automount: Got automount request for
/nfs/project, triggered by 10521 (restorecon)
  systemd[1]: Mounting /nfs/project...
  nfsrahead[10533]: setting /nfs/project readahead to 128
  systemd[1]: Mounted /nfs/project.
  systemd[1]: nfs-scratch.automount: Got automount request for
/nfs/scratch, triggered by 10521 (restorecon)
  systemd[1]: Mounting /nfs/scratch...
  nfsrahead[10536]: setting /nfs/scratch readahead to 128
  systemd[1]: Mounted /nfs/scratch.

The fstab entries are:

  nfs_server:/home /nfs/home nfs4
proto=tcp,nosuid,nolock,noatime,actimeo=3,nfsvers=4.2,seclabel,_netdev,x-systemd.automount,x-systemd.mount-timeout=30
0 0
  nfs_server:/project /nfs/project nfs4
proto=tcp,nosuid,nolock,noatime,actimeo=3,nfsvers=4.2,seclabel,_netdev,x-systemd.automount,x-systemd.mount-timeout=30
0 0
  nfs_server:/scratch /nfs/scratch nfs4
proto=tcp,nosuid,nolock,noatime,actimeo=3,nfsvers=4.2,seclabel,_netdev,x-systemd.automount,x-systemd.mount-timeout=30
0 0

An strace shows restorecon probing these mountpoints:

  $ strace -f restorecon /etc/krb5.conf/freeipa 2>&1 | grep /nfs

  statfs("/nfs/home", {f_type=NFS_SUPER_MAGIC, f_bsize=1048576,
f_blocks=10172, f_bfree=10069, f_bavail=10069, f_files=5240832,
f_ffree=5240755, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=1048576,
f_flags=ST_VALID|ST_NOSUID|ST_NOATIME}) = 0
  statfs("/nfs/project", {f_type=NFS_SUPER_MAGIC, f_bsize=1048576,
f_blocks=10172, f_bfree=10069, f_bavail=10069, f_files=5240832,
f_ffree=5240816, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=1048576,
f_flags=ST_VALID|ST_NOSUID|ST_NOATIME}) = 0
  statfs("/nfs/scratch", {f_type=NFS_SUPER_MAGIC, f_bsize=1048576,
f_blocks=10172, f_bfree=10069, f_bavail=10069, f_files=5240832,
f_ffree=5240818, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=1048576,
f_flags=ST_VALID|ST_NOSUID|ST_NOATIME}) = 0

My understanding is:

1. When restorecon is called without ignore mount (-m) flag, it reads
the mount table to construct the exclusion list for filesystems
without SELinux labeling support.
https://github.com/SELinuxProject/selinux/blob/main/libselinux/src/selinux_restorecon.c#L146C14-L146C28
2. exclude_non_seclabel_mounts() calls file_system_count() for mounts that
advertise the seclabel option. file_system_count() calls statvfs() on
the mountpoint.
https://github.com/SELinuxProject/selinux/blob/main/libselinux/src/selinux_restorecon.c#L343
https://github.com/SELinuxProject/selinux/blob/main/libselinux/src/selinux_restorecon.c#L282
3. Calling statvfs() on a autofs mountpoint activates the underlying mount.
4. The resulting file count appears to be used only for progress reporting, but
it is calculated even when neither progress nor mass-relabel reporting
was requested.

So a non-recursive restorecon operation on one local file can mount
unrelated remote filesystems.

I would expect restorecon to not activate unrelated systemd automount
filesystems when progress reporting is not requested and the target
does not traverse those filesystems.

I think the best minimal patch would to skip calling file_system_count on
mounts which type is autofs (mount_info[2]).

---<snip>---

Fix this issue as the original reporter suggested.

Reported-by: Félix-Antoine Fortin <[email protected]>
Suggested-by: Félix-Antoine Fortin <[email protected]>
Signed-off-by: Stephen Smalley <[email protected]>
---
 libselinux/src/selinux_restorecon.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c
index 30f1b836..8bae1464 100644
--- a/libselinux/src/selinux_restorecon.c
+++ b/libselinux/src/selinux_restorecon.c
@@ -301,6 +301,7 @@ static uint64_t exclude_non_seclabel_mounts(void)
 	uint64_t nfile = 0;
 	char *mount_info[4];
 	char *buf = NULL, *item, *saveptr;
+	bool autofs = false;
 
 	/* Check to see if the kernel supports seclabel */
 	if (uname(&uts) == 0 && strverscmp(uts.release, "2.6.30") < 0)
@@ -335,12 +336,19 @@ static uint64_t exclude_non_seclabel_mounts(void)
 		/* Remove pre-existing entry */
 		remove_exclude(mount_info[1]);
 
+		autofs = !strcmp(mount_info[2], "autofs");
 		saveptr = NULL;
 		item = strtok_r(mount_info[3], ",", &saveptr);
 		while (item != NULL) {
 			if (strcmp(item, "seclabel") == 0) {
 				found = 1;
-				nfile += file_system_count(mount_info[1]);
+				/*
+				 * Avoid triggering an auto-mount just to
+				 * count files for progress tracking.
+				 */
+				if (!autofs)
+					nfile += file_system_count(
+						mount_info[1]);
 				break;
 			}
 			item = strtok_r(NULL, ",", &saveptr);
-- 
2.55.0