All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ted Ts'o <tytso@mit.edu>
To: Tao Ma <tm@tao.ma>
Cc: linux-ext4@vger.kernel.org, stable <stable@vger.kernel.org>
Subject: Re: [PATCH] ext4: Save and restore state flags in EXT4_IOC_SETFLAGS.
Date: Thu, 31 May 2012 23:48:20 -0400	[thread overview]
Message-ID: <20120601034820.GC7897@thunk.org> (raw)
In-Reply-To: <1336145869-4120-1-git-send-email-tm@tao.ma>

On Fri, May 04, 2012 at 11:37:49PM +0800, Tao Ma wrote:
> From: Tao Ma <boyu.mt@taobao.com>
> 
> In commit 353eb83c we removes i_state_flags with 64-bit longs,
> But in case we call EXT4_IOC_SETFLAGS, we fail to save the
> high 32-bit state flags and only stores the low 32-bit back
> to ei->i_flags. So the state flags are missing now in 64-bit
> long architecture.

The problem with this approach is that we are still editing i_flags
and then replacing it with the new value.  So we're vulnerable to
races where some other process is modifies the i_state_flags between
when we sample it using ext4_save_state_flags() and when we restore
them.

This is a better way to fix the problem, and what I plan to commit
into the ext4 tree:

commit 79906964a187c405db72a3abc60eb9b50d804fbc
Author: Theodore Ts'o <tytso@mit.edu>
Date:   Thu May 31 23:46:01 2012 -0400

    ext4: don't trash state flags in EXT4_IOC_SETFLAGS
    
    In commit 353eb83c we removed i_state_flags with 64-bit longs, But
    when handling the EXT4_IOC_SETFLAGS ioctl, we replace i_flags
    directly, which trashes the state flags which are stored in the high
    32-bits of i_flags on 64-bit platforms.  So use the the
    ext4_{set,clear}_inode_flags() functions which use atomic bit
    manipulation functions instead.
    
    Reported-by: Tao Ma <boyu.mt@taobao.com>
    Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
    Cc: stable@kernel.org

diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index feba55a..8ad112a 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -38,7 +38,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 		handle_t *handle = NULL;
 		int err, migrate = 0;
 		struct ext4_iloc iloc;
-		unsigned int oldflags;
+		unsigned int oldflags, mask, i;
 		unsigned int jflag;
 
 		if (!inode_owner_or_capable(inode))
@@ -115,8 +115,14 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 		if (err)
 			goto flags_err;
 
-		flags = flags & EXT4_FL_USER_MODIFIABLE;
-		flags |= oldflags & ~EXT4_FL_USER_MODIFIABLE;
+		for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
+			if (!(mask & EXT4_FL_USER_MODIFIABLE))
+				continue;
+			if (mask & flags)
+				ext4_set_inode_flag(inode, i);
+			else
+				ext4_clear_inode_flag(inode, i);
+		}
 		ei->i_flags = flags;
 
 		ext4_set_inode_flags(inode);



  parent reply	other threads:[~2012-06-01  3:48 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-04 15:37 [PATCH] ext4: Save and restore state flags in EXT4_IOC_SETFLAGS Tao Ma
2012-05-30  1:59 ` Tao Ma
2012-06-01  3:48 ` Ted Ts'o [this message]
2012-06-04  3:22   ` Tao Ma

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120601034820.GC7897@thunk.org \
    --to=tytso@mit.edu \
    --cc=linux-ext4@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tm@tao.ma \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.