Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Apr 2005 08:52:28 +0200 (CEST)
From:      Andre Albsmeier <Andre.Albsmeier@siemens.com>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/80390: fstatfs() returns wrong flags or libexec/rtld-elf/rtld.c is broken
Message-ID:  <200504270652.j3R6qSxv038497@curry.mchp.siemens.de>
Resent-Message-ID: <200504270700.j3R70Xxt053306@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         80390
>Category:       kern
>Synopsis:       fstatfs() returns wrong flags or libexec/rtld-elf/rtld.c is broken
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Apr 27 07:00:32 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Andre Albsmeier
>Release:        FreeBSD 5.4-STABLE i386
>Organization:
>Environment:

FreeBSD 5.4-STABLE i386 used as NFS client

>Description:

On a FreeBSD 5.4-STABLE system fstatfs() used on an NFS mounted
volume now returns the NFS mount option flags (as defined in
sys/nfsclient/nfsargs.h) instead of the "normal" filesystem
flags as defined in sys/sys/mount.h.

This means that if you mount the remote fs with the -r (set read
size) option set, fstatfs() will return a value with NFSMNT_RSIZE
(0x00000004) set.

However, libexec/rtld-elf/rtld.c uses the result of fstatfs()
to determine if someone tried to circumvent a possibly set
noexec flag on the filesystem, see
http://www.freebsd.org/cgi/cvsweb.cgi/src/libexec/rtld-elf/rtld.c.diff?r1=1.104&r2=1.105

Therefore, an NFS fs which has been mounted using -r, appears to
rtld.c as if the -o noexec option was given.


>How-To-Repeat:

Mount an NFS filesystem using -r on a 5.4-STABLE client.
Try to build perl5.8 from ports on it (The perl build tries
to execute some "LD_LIBRARY_PATH=blahblah ./miniperl ..."
command which fails due to the MNT_NOEXEC seen by the linker).

>Fix:

"man fstatfs" clearly states that the returned flags are the
"normal" filesystem flags as defined in sys/sys/mount.h.

If it is intended that fstatfs() now returns the NFS mount option
flags (as defined in sys/nfsclient/nfsargs.h), rtld.c and the
fstatfs manpage must be fixed.

Otherwise, the following patch restores the old behaviour
as known from FreeBSD-4 and as documented in the manpage:

--- sys/kern/vfs_syscalls.c.ORI	Mon Feb 28 06:54:34 2005
+++ sys/kern/vfs_syscalls.c	Wed Apr 27 08:44:26 2005
@@ -242,10 +242,10 @@
 	 */
 	sp->f_version = STATFS_VERSION;
 	sp->f_namemax = NAME_MAX;
-	sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
 	error = VFS_STATFS(mp, sp, td);
 	if (error)
 		return (error);
+	sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
 	if (suser(td)) {
 		bcopy(sp, &sb, sizeof(sb));
 		sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
@@ -293,10 +293,10 @@
 	 */
 	sp->f_version = STATFS_VERSION;
 	sp->f_namemax = NAME_MAX;
-	sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
 	error = VFS_STATFS(mp, sp, td);
 	if (error)
 		return (error);
+	sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
 	if (suser(td)) {
 		bcopy(sp, &sb, sizeof(sb));
 		sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
@@ -356,7 +356,6 @@
 			 */
 			sp->f_version = STATFS_VERSION;
 			sp->f_namemax = NAME_MAX;
-			sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
 			/*
 			 * If MNT_NOWAIT or MNT_LAZY is specified, do not
 			 * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
@@ -370,6 +369,7 @@
 				vfs_unbusy(mp, td);
 				continue;
 			}
+			sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
 			if (suser(td)) {
 				bcopy(sp, &sb, sizeof(sb));
 				sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200504270652.j3R6qSxv038497>