lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20110106175526.GA2857@thunk.org>
Date:	Thu, 6 Jan 2011 12:55:26 -0500
From:	Ted Ts'o <tytso@....edu>
To:	Andreas Dilger <adilger.kernel@...ger.ca>
Cc:	Ext4 Developers List <linux-ext4@...r.kernel.org>
Subject: Re: [PATCH 5/6] ext4: Drop i_state_flags on architectures with
 64-bit longs

On Thu, Jan 06, 2011 at 12:23:53AM -0700, Andreas Dilger wrote:
> > Yeah, I did think of this, but it seemed like extra/needless work that
> > I was trying to optimize away.  It's still not safe to do:
> > 
> > #define EXT4_CLEAR_STATE_FLAGS(ei)      (ei)->i_flags &= 0xffffffffULL;
> > 
> > ... since we're not atomically updating i_flags.
> 
> This code would only be used on a 64-bit arch, so it should be
> updating the whole word at once (unlike a 32-bit arch).

Masking off the low 32-bits is a read / mask / write set of operations
on RISCy architectures.  Even on an Intel architecture, unless you
specifically use the LOCK prefix on the AND operation, you can still
risk racing with another CPU while you do the mask operation.  So no,
it's not atomic.

This is why we did a wholesale replacement of explicit C bit
operations on ei->i_flags and replaced them with
ext4_{set/get/clear}_inode_flags.  And why in the jbd/jbd2 layer, we
take an explicit spinlock before modifying j_flags.  (An obvious thing
to try doing to reduce spinlock contention on big 48-core machines is
to replace do a similar replacement in the jbd2 layer; on my todo
list.)

> > I did think about putting the #ifdef BITS_PER_LONG < 64 inline in the
> > code, but that's ugly.  
> 
> I'm missing the point of that - isn't the EXT4_CLEAR_STATE_FLAGS() macro
> masking already conditional on 64-bit architectures?

Sorry, I must not have been clear.  I was referring to putting in an
inline #if statement into the C code as being ugly.

> The one call in ext4_do_update_inode() that is masking i_flags is redundant,
> since the cpu_to_le32() macro is itself either masking the value before
> swabbing, and/or it is truncated by the assignment to i_flags.

(Actually, I think the C compiler will likely notice that the earlier
i_flags is redudant, and optimize it out.)

I could have replaced things with this instead:

#if BITS_PER_LONG < 64
	ei->i_state_flags = 0
#endif

That's more "correct", but it's ugly.  On the other hand, it does make
explicit what is going on, instead of hiding it in a header file.
Whether we think it's better depends on how likely that people will
get confused in the future.  If we think it's likely this section of
code will be regularly modified, then we can keep it explicit to
minimize the chances that a future change in the code will move things
around and I don't notice when I'm reviewing the patch.

If we think the section of code is less likely to be changed, then
hiding this detail could make it easier for the casual reader to
understand the code.

To be honoest, it's a minor point either way.  I don't have strong
feelings about how this gets done one way or another; I just had to
pick one, and I went with the latter approach.  I'm certainly willing
to be pursuaded otherwise that the chances that someone could fall
into the pitfall would be huge.

						- Ted
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ