Re: Patch "ext4: atomically set inode->i_flags in ext4_set_inode_flags()" has been added to the 3.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Mar 31, 2014 at 03:15:44PM -0700, gregkh@xxxxxxxxxxxxxxxxxxx wrote:
> 
> This is a note to let you know that I've just added the patch titled
> 
>     ext4: atomically set inode->i_flags in ext4_set_inode_flags()
> 
> to the 3.10-stable tree which can be found at:
>     http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
> 
> The filename of the patch is:
>      ext4-atomically-set-inode-i_flags-in-ext4_set_inode_flags.patch
> and it can be found in the queue-3.10 subdirectory.

I was going to make a one or two minor changes based on akpm's
changes, and this change hasn't been merged upstream yet.  The plan
was for this to go upstream in a few more days, after we finish off
some last minute testing, and and fixing a bug in an existing patch in
the ext4 tree that was discovered last week, so if you want to wait a
week, this patch should be upstream by then (and hopefully sooner).

OTOH, this is a security fix, and the bug has been reported and
outstanding for a while, so if you want to push this sooner, that's
fine.

It should also be noted that a similar bug exists for btrfs and
several other file systems (although btrfs is probably the most
important mainstream fs that should get fixed sooner rather than
later).

Cheers,

						- Ted

> If you, or anyone else, feels it should not be added to the stable tree,
> please let <stable@xxxxxxxxxxxxxxx> know about it.
> 
> 
> From 00a1a053ebe5febcfc2ec498bd894f035ad2aa06 Mon Sep 17 00:00:00 2001
> From: Theodore Ts'o <tytso@xxxxxxx>
> Date: Sun, 30 Mar 2014 10:20:01 -0400
> Subject: ext4: atomically set inode->i_flags in ext4_set_inode_flags()
> 
> From: Theodore Ts'o <tytso@xxxxxxx>
> 
> commit 00a1a053ebe5febcfc2ec498bd894f035ad2aa06 upstream.
> 
> Use cmpxchg() to atomically set i_flags instead of clearing out the
> S_IMMUTABLE, S_APPEND, etc. flags and then setting them from the
> EXT4_IMMUTABLE_FL, EXT4_APPEND_FL flags, since this opens up a race
> where an immutable file has the immutable flag cleared for a brief
> window of time.
> 
> Reported-by: John Sullivan <jsrhbz@xxxxxxxxxxxxxxxxxxxx>
> Signed-off-by: "Theodore Ts'o" <tytso@xxxxxxx>
> Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
> 
> ---
>  fs/ext4/inode.c        |   15 +++++++++------
>  include/linux/bitops.h |   15 +++++++++++++++
>  2 files changed, 24 insertions(+), 6 deletions(-)
> 
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -38,6 +38,7 @@
>  #include <linux/slab.h>
>  #include <linux/ratelimit.h>
>  #include <linux/aio.h>
> +#include <linux/bitops.h>
>  
>  #include "ext4_jbd2.h"
>  #include "xattr.h"
> @@ -4044,18 +4045,20 @@ int ext4_get_inode_loc(struct inode *ino
>  void ext4_set_inode_flags(struct inode *inode)
>  {
>  	unsigned int flags = EXT4_I(inode)->i_flags;
> +	unsigned int new_fl = 0;
>  
> -	inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
>  	if (flags & EXT4_SYNC_FL)
> -		inode->i_flags |= S_SYNC;
> +		new_fl |= S_SYNC;
>  	if (flags & EXT4_APPEND_FL)
> -		inode->i_flags |= S_APPEND;
> +		new_fl |= S_APPEND;
>  	if (flags & EXT4_IMMUTABLE_FL)
> -		inode->i_flags |= S_IMMUTABLE;
> +		new_fl |= S_IMMUTABLE;
>  	if (flags & EXT4_NOATIME_FL)
> -		inode->i_flags |= S_NOATIME;
> +		new_fl |= S_NOATIME;
>  	if (flags & EXT4_DIRSYNC_FL)
> -		inode->i_flags |= S_DIRSYNC;
> +		new_fl |= S_DIRSYNC;
> +	set_mask_bits(&inode->i_flags,
> +		      S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC, new_fl);
>  }
>  
>  /* Propagate flags from i_flags to EXT4_I(inode)->i_flags */
> --- a/include/linux/bitops.h
> +++ b/include/linux/bitops.h
> @@ -185,6 +185,21 @@ static inline unsigned long __ffs64(u64
>  
>  #ifdef __KERNEL__
>  
> +#ifndef set_mask_bits
> +#define set_mask_bits(ptr, _mask, _bits)	\
> +({								\
> +	const typeof(*ptr) mask = (_mask), bits = (_bits);	\
> +	typeof(*ptr) old, new;					\
> +								\
> +	do {							\
> +		old = ACCESS_ONCE(*ptr);			\
> +		new = (old & ~mask) | bits;			\
> +	} while (cmpxchg(ptr, old, new) != old);		\
> +								\
> +	new;							\
> +})
> +#endif
> +
>  #ifndef find_last_bit
>  /**
>   * find_last_bit - find the last set bit in a memory region
> 
> 
> Patches currently in stable-queue which might be from tytso@xxxxxxx are
> 
> queue-3.10/ext4-atomically-set-inode-i_flags-in-ext4_set_inode_flags.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]