bin/89782: [PATCH] avoid double mounts if the mount point is a symlink

Andreas Kohn andreas at syndrom23.de
Thu Dec 1 03:00:29 GMT 2005


>Number:         89782
>Category:       bin
>Synopsis:       [PATCH] avoid double mounts if the mount point is a symlink
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Dec 01 03:00:13 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Andreas Kohn
>Release:        FreeBSD 7.0-CURRENT i386
>Organization:
>Environment:


System: FreeBSD 7.0-CURRENT #6: Tue Nov 29 03:37:45 CET 2005
    root at xentros.syndrom23.de:/usr/obj/usr/src/sys/XENTROS



>Description:


My /etc/fstab contains the following line
linprocfs /compat/linux/proc linprocfs ....,
which is suggested by java/jdk15 port for instance.

mount checks if a file system is mounted before mounting it with
mount -a and others, but doesn't consider symlinks. /compat is a link to /usr/compat, and so the check in ismounted() does not detect that linprocfs is mounted, and will mount it twice if mount -a is called twice.
This could for example happen if you boot to single user, mount -a your devices and then exit single user mode to multiuser mode (somewhere in the process mount -a will be called).


>How-To-Repeat:


Add a line to /etc/fstab that has a mountpoint that is a symlink.
Call mount /this/mountpoint multiple times, and observe that this mount is shown multiple times in mount output.



>Fix:


The fix here uses realpath to resolve the mountpoint from /etc/fstab
into a non-symlink path, and compares that path to struct statfs->f_mntonname. It fixes the problem for me. 

Alternative approaches would be to discourage the use of symlinks for mountpoints. This would then require to rewrite all ports that use /compat/linux instead of /usr/compat/linux etc.

rodrigc@ Cc'ed, because he was working on mount recently. I do not know if this repeated mounting may be a regression.

--- mount-symlinks.diff begins here ---
Index: sbin/mount/mount.c
===================================================================
RCS file: /storage/freebsd/cvs/src/sbin/mount/mount.c,v
retrieving revision 1.76
diff -u -r1.76 mount.c
--- sbin/mount/mount.c	24 Nov 2005 17:35:05 -0000	1.76
+++ sbin/mount/mount.c	30 Nov 2005 17:21:14 -0000
@@ -392,13 +392,18 @@
 ismounted(struct fstab *fs, struct statfs *mntbuf, int mntsize)
 {
 	int i;
+	char realfsfile[PATH_MAX];
 
 	if (fs->fs_file[0] == '/' && fs->fs_file[1] == '\0')
 		/* the root file system can always be remounted */
 		return (0);
 
+	/* The user may have specified a symlink in fstab, resolve the path */
+	if (realpath(fs->fs_file, realfsfile) == NULL)
+	    err(1, "%s cannot be resolved to a path", fs->fs_file);
+
 	for (i = mntsize - 1; i >= 0; --i)
-		if (strcmp(fs->fs_file, mntbuf[i].f_mntonname) == 0 &&
+		if (strcmp(realfsfile, mntbuf[i].f_mntonname) == 0 &&
 		    (!isremountable(fs->fs_vfstype) ||
 		     strcmp(fs->fs_spec, mntbuf[i].f_mntfromname) == 0))
 			return (1);
--- mount-symlinks.diff ends here ---



>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list