Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 02 Jun 2008 01:05:03 -0430
From:      Ighighi <ighighi@gmail.com>
To:        bug-followup@freebsd.org
Cc:        freebsd-fs@freebsd.org
Subject:   Re: kern/122047: [ext2fs] incorrect handling of UF_IMMUTABLE / UF_APPEND, flag on EXT2FS (maybe others)
Message-ID:  <48438687.1080606@gmail.com>

next in thread | raw e-mail | index | archive | help
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--



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