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: <5402183a-2372-b442-84d3-c28fb59fa7af@nvidia.com>
Date:   Sat, 8 Feb 2020 17:44:38 -0800
From:   John Hubbard <jhubbard@...dia.com>
To:     Marco Elver <elver@...gle.com>, Qian Cai <cai@....pw>
CC:     Jan Kara <jack@...e.cz>, David Hildenbrand <david@...hat.com>,
        Andrew Morton <akpm@...ux-foundation.org>,
        <ira.weiny@...el.com>, Dan Williams <dan.j.williams@...el.com>,
        Linux Memory Management List <linux-mm@...ck.org>,
        Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
        "Paul E. McKenney" <paulmck@...nel.org>
Subject: Re: [PATCH] mm: fix a data race in put_page()

On 2/7/20 5:17 AM, Marco Elver wrote:
...
>> Yes. I'm grasping at straws now, but...what about the idiom that page_zonenum()
>> uses: a set of bits that are "always" (after a certain early point) read-only?
>> What are your thoughts on that?
> 
> Without annotations it's hard to tell. The problem is that the
> compiler can still emit a word-sized load, even if you're just
> checking 1 bit. The instrumentation emitted for KCSAN only cares about
> loads/stores, where access size is in number of bytes and not bits,
> since that's what the compiler has to emit.  So, strictly speaking
> these are data races: concurrent reads / writes where at least one
> access is plain.
> 
> With the above caveat out of the way, we already have the following
> defaults in KCSAN (after similar requests):
> 1. KCSAN ignores same-value stores, i.e. races with writes that appear
> to write the same value do not result in data race reports.
> 2. KCSAN does not demand aligned writes (including things like 'var++'
> if there are no concurrent writers) up to word size to be marked (with
> READ_ONCE etc.), assuming there is no way for the compiler to screw
> these up. [I still recommend writes to be marked though, if at all
> possible, because I'm still not entirely convinced it's always safe!]
> 
> So, because of (2), KCSAN will not complain if you have something like
> 'flags |= SOME_FLAG' (where the read is marked). Because of (1), it'll
> still complain about 'flags & SOME_FLAG' though, since the load is not
> marked, and only sees this is a word-sized access (assuming flags is a
> long) where a bit changed.
> 
> I don't think it's possible to easily convey to KCSAN which bits of an
> access you only care about, so that we could extend (1).   Ideas?


I'm drawing a blank as far as easy ways forward, so I'm just going accept
the compiler word-level constraints as a "given". I was hoping maybe you
had some magic available, just checking. :)


> 
>>>> A similar thing was brought up before, i.e., anything compared to zero is immune to load-tearing
>>>> issues, but it is rather difficult to implement it in the compiler, so it was settled to use data_race(),
>>>>
>>>> https://lore.kernel.org/lkml/CANpmjNN8J1oWtLPHTgCwbbtTuU_Js-8HD=cozW5cYkm8h-GTBg@mail.gmail.com/#r
>>>>
>>>
>>> Thanks for that link to the previous discussion, good context.
>>>
>>>>>
>>>>> b) Add a new, better-named macro to indicate what's going on. Initial bikeshed-able
>>>>>  candidates:
>>>>>
>>>>>     READ_RO_BITS()
>>>>>     READ_IMMUTABLE_BITS()
>>>>>     ...etc...
>>>>>
> 
> This could work, but 'READ_BITS()' is enough, if KCSAN's same-value
> filter is default on anyway.  Although my preference is also to avoid
> more macros if possible.


So it looks like we're probably stuck with having to annotate the code. Given
that, there is a balance between how many macros, and how much commenting. For
example, if there is a single macro (data_race, for example), then we'll need to
add comments for the various cases, explaining which data_race situation is 
happening.

That's still true, but to a lesser extent if more macros are added. In this case,
I suspect that READ_BITS() makes the commenting easier and shorter. So I'd tentatively
lead towards adding it, but what do others on the list think?



thanks,
-- 
John Hubbard
NVIDIA

> 
>>>> Actually, Linus might hate those kinds of complication rather than a simple data_race() macro,
>>>>
>>>> https://lore.kernel.org/linux-fsdevel/CAHk-=wg5CkOEF8DTez1Qu0XTEFw_oHhxN98bDnFqbY7HL5AB2g@mail.gmail.com/
>>>>
>>>
>>> Another good link. However, my macros above haven't been proposed yet, and I'm perfectly
>>> comfortable proposing something that Linus *might* (or might not!) hate. No point in
>>> guessing about it, IMHO.
>>>
>>> If you want, I'll be happy to put on my flame suit and post a patchset proposing
>>> READ_IMMUTABLE_BITS() (or a better-named thing, if someone has another name idea).  :)
>>>
>>
>> BTW, the current comment said (note, it is called “access” which in this case it does read the whole word
>> rather than those 3 bits, even though it is only those bits are of interested for us),
>>
>> /*
>>  * data_race(): macro to document that accesses in an expression may conflict with
>>  * other concurrent accesses resulting in data races, but the resulting
>>  * behaviour is deemed safe regardless.
>>  *
>>  * This macro *does not* affect normal code generation, but is a hint to tooling
>>  * that data races here should be ignored.
>>  */
>>
>> Macro might have more to say.
> 
> I agree that data_race() would be the most suitable here, since
> technically it's still a data race. It just so happens that we end up
> "throwing away" most of the bits of the access, and just care about a
> few bits.
> 
> Thanks,
> -- Marco
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ