kern/122047: [ext2fs] incorrect handling of UF_IMMUTABLE /
UF_APPEND, flag on EXT2FS (maybe others)
Ighighi
ighighi at gmail.com
Mon Jun 2 05:40:03 UTC 2008
The following reply was made to PR kern/122047; it has been noted by GNATS.
From: Ighighi <ighighi at gmail.com>
To: bug-followup at freebsd.org
Cc: freebsd-fs at freebsd.org
Subject: Re: kern/122047: [ext2fs] incorrect handling of UF_IMMUTABLE / UF_APPEND,
flag on EXT2FS (maybe others)
Date: Mon, 02 Jun 2008 01:05:03 -0430
This is a multi-part message in MIME format.
--------------050007060101030401040504
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
On Linux, only the root user may set/clear the immutable/append flags
on ext2 filesystems... Shouldn't FreeBSD do this too, as a POLA?
Anyway the attached patch extends the previous one by making it possible
to follow the current Linux convention by setting the sysctl to 0.
Setting it to 1, allows normal users to set them as well, and setting it
to -1 preserves current (though erroneous) FreeBSD behavior.
--------------050007060101030401040504
Content-Type: text/plain;
name="ext2fs.patch.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="ext2fs.patch.txt"
#
# (!c) 2008 by Ighighi
#
# See http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/122047
#
# This patch adds a vfs.e2fs.userflags sysctl to allow/prevent normal users
# to set/clear the append/immutable filesystem flags on EXT2 filesystems.
# If set to 0, only the superuser may set/clear these flags. This is the
# default behavior on Linux, which FreeBSD should mimick (POLA).
# If set to 1, users are also permitted to set/clear them on files they own.
# If set to -1 (default), maintain the current (erroneus) behavior.
#
# As a bonus, this patch sets st_birthtime to zero.
#
# Built and tested on FreeBSD 6.3-STABLE (RELENG_6).
# Known to patch on -CURRENT
#
# To install, run as root:
# /sbin/umount -v -t ext2fs -a
# /sbin/kldunload -v ext2fs
# /usr/bin/patch -d /usr < /path/to/ext2fs.patch
# cd /sys/modules/ext2fs/
# make clean obj depend && make && make install
# /sbin/kldload -v ext2fs
# /sbin/sysctl vfs.e2fs.userflags=1
# /sbin/mount -v -t ext2fs -a
#
--- src/sys/gnu/fs/ext2fs/ext2_inode_cnv.c.orig 2005-06-14 22:36:10.000000000 -0400
+++ src/sys/gnu/fs/ext2fs/ext2_inode_cnv.c 2008-06-02 00:35:34.658524358 -0430
@@ -30,11 +30,19 @@
#include <sys/lock.h>
#include <sys/stat.h>
#include <sys/vnode.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
#include <gnu/fs/ext2fs/inode.h>
#include <gnu/fs/ext2fs/ext2_fs.h>
#include <gnu/fs/ext2fs/ext2_extern.h>
+SYSCTL_DECL(_vfs_e2fs);
+
+static int userflags = -1;
+SYSCTL_INT(_vfs_e2fs, OID_AUTO, userflags, CTLFLAG_RW,
+ &userflags, 0, "Users may set/clear filesystem flags");
+
void
ext2_print_inode( in )
struct inode *in;
@@ -83,8 +91,37 @@ ext2_ei2i(ei, ip)
ip->i_mtime = ei->i_mtime;
ip->i_ctime = ei->i_ctime;
ip->i_flags = 0;
- ip->i_flags |= (ei->i_flags & EXT2_APPEND_FL) ? APPEND : 0;
- ip->i_flags |= (ei->i_flags & EXT2_IMMUTABLE_FL) ? IMMUTABLE : 0;
+ switch (userflags) {
+ case 0:
+ /*
+ * Only the superuser may set/clear these flags.
+ * This is the current behavior on Linux.
+ */
+ if (ei->i_flags & EXT2_APPEND_FL)
+ ip->i_flags |= SF_APPEND;
+ if (ei->i_flags & EXT2_IMMUTABLE_FL)
+ ip->i_flags |= SF_IMMUTABLE;
+ break;
+ case 1:
+ /*
+ * Users may set/clear these flags on files they own.
+ */
+ if (ei->i_flags & EXT2_APPEND_FL)
+ ip->i_flags |= UF_APPEND;
+ if (ei->i_flags & EXT2_IMMUTABLE_FL)
+ ip->i_flags |= UF_IMMUTABLE;
+ break;
+ case -1:
+ default:
+ /*
+ * Default behavior on FreeBSD
+ */
+ if (ei->i_flags & EXT2_APPEND_FL)
+ ip->i_flags |= APPEND;
+ if (ei->i_flags & EXT2_IMMUTABLE_FL)
+ ip->i_flags |= IMMUTABLE;
+ break;
+ }
ip->i_blocks = ei->i_blocks;
ip->i_gen = ei->i_generation;
ip->i_uid = ei->i_uid;
@@ -121,8 +158,37 @@ ext2_i2ei(ip, ei)
ei->i_ctime = ip->i_ctime;
ei->i_flags = ip->i_flags;
ei->i_flags = 0;
- ei->i_flags |= (ip->i_flags & APPEND) ? EXT2_APPEND_FL: 0;
- ei->i_flags |= (ip->i_flags & IMMUTABLE) ? EXT2_IMMUTABLE_FL: 0;
+ switch (userflags) {
+ case 0:
+ /*
+ * Only the superuser may set/clear these flags.
+ * This is the current behavior on Linux.
+ */
+ if (ip->i_flags & SF_APPEND)
+ ei->i_flags |= EXT2_APPEND_FL;
+ if (ip->i_flags & SF_IMMUTABLE)
+ ei->i_flags |= EXT2_IMMUTABLE_FL;
+ break;
+ case 1:
+ /*
+ * Users may set/clear these flags on files they own.
+ */
+ if (ip->i_flags & UF_APPEND)
+ ei->i_flags |= EXT2_APPEND_FL;
+ if (ip->i_flags & UF_IMMUTABLE)
+ ei->i_flags |= EXT2_IMMUTABLE_FL;
+ break;
+ case -1:
+ default:
+ /*
+ * Default behavior on FreeBSD
+ */
+ if (ip->i_flags & APPEND)
+ ei->i_flags |= EXT2_APPEND_FL;
+ if (ip->i_flags & IMMUTABLE)
+ ei->i_flags |= EXT2_IMMUTABLE_FL;
+ break;
+ }
ei->i_blocks = ip->i_blocks;
ei->i_generation = ip->i_gen;
ei->i_uid = ip->i_uid;
--- src/sys/gnu/fs/ext2fs/ext2_lookup.c.orig 2006-01-04 15:32:00.000000000 -0400
+++ src/sys/gnu/fs/ext2fs/ext2_lookup.c 2008-06-01 05:38:42.363332933 -0430
@@ -66,7 +66,7 @@ static int dirchk = 1;
static int dirchk = 0;
#endif
-static SYSCTL_NODE(_vfs, OID_AUTO, e2fs, CTLFLAG_RD, 0, "EXT2FS filesystem");
+SYSCTL_NODE(_vfs, OID_AUTO, e2fs, CTLFLAG_RD, 0, "EXT2FS filesystem");
SYSCTL_INT(_vfs_e2fs, OID_AUTO, dircheck, CTLFLAG_RW, &dirchk, 0, "");
/*
--- src/sys/gnu/fs/ext2fs/ext2_vnops.c.orig 2006-02-19 20:53:14.000000000 -0400
+++ src/sys/gnu/fs/ext2fs/ext2_vnops.c 2008-05-28 07:58:02.189157441 -0430
@@ -358,6 +358,8 @@ ext2_getattr(ap)
vap->va_mtime.tv_nsec = ip->i_mtimensec;
vap->va_ctime.tv_sec = ip->i_ctime;
vap->va_ctime.tv_nsec = ip->i_ctimensec;
+ vap->va_birthtime.tv_sec = 0;
+ vap->va_birthtime.tv_nsec = 0;
vap->va_flags = ip->i_flags;
vap->va_gen = ip->i_gen;
vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
--------------050007060101030401040504--
More information about the freebsd-bugs
mailing list