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