kern/80390: fstatfs() returns wrong flags or
libexec/rtld-elf/rtld.c is broken
Andre Albsmeier
Andre.Albsmeier at siemens.com
Wed Apr 27 00:00:33 PDT 2005
>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:
More information about the freebsd-bugs
mailing list