linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jiri Kosina <jkosina@suse.cz>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Colin Walters <walters@verbum.org>, Jan Kara <jack@suse.cz>,
	LKML <linux-kernel@vger.kernel.org>,
	linux-ia64@vger.kernel.org, dsterba@suse.cz, ptesarik@suse.cz,
	rguenther@suse.de, gcc@gcc.gnu.org
Subject: Re: Memory corruption due to word sharing
Date: Wed, 1 Feb 2012 18:11:29 +0100 (CET)	[thread overview]
Message-ID: <alpine.LRH.2.00.1202011808240.22725@twin.jikos.cz> (raw)
In-Reply-To: <CA+55aFxmdskUXX1iBaPx7rUGD95UqNJxhe1BLeVtZjqHjBpsPA@mail.gmail.com>

On Wed, 1 Feb 2012, Linus Torvalds wrote:

> But the compiler turns the access to the bitfield (in a 32-bit aligned
> word) into a 64-bit access that accesses the word *next* to it.
> 
> That word next to it might *be* the lock, for example.
> 
> So we could literally have this kind of situation:
> 
>    struct {
>       atomic_t counter;
>       unsigned int val:4, other:4, data:24;
>    };
> 
> and if we write code like this:
> 
>     spin_lock(&somelock);
>     s->data++;
>     spin_unlock(&somelock);
> 
> and on another CPU we might do
> 
>    atomic_inc(&counter);
> 
> and the access to the bitfield will *corrupt* the atomic counter, even
> though both of them are perfectly fine!
> 
> Quite frankly, if the bug is simply because gcc doesn't actually know
> or care about the underlying size of the bitmask, it is possible that
> we can find a case where gcc clearly is buggy even according to the
> original C rules.
> 
> Honza - since you have access to the compiler in question, try
> compiling this trivial test-program:
> 
> 
>    struct example {
>       volatile int a;
>       int b:1;
>    };
> 
>    ..
>      s->b = 1;
>    ..
> 
> and if that bitfield access actually does a 64-bit access that also
> touches 's->a', then dammit, that's a clear violation of even the
> *old* C standard, and the gcc people cannot just wave away their bugs
> by saying "we've got standads, pttthththt".
> 
> And I suspect it really is a generic bug that can be shown even with
> the above trivial example.

I have actually tried exactly this earlier today (because while looking at 
this, I had an idea that putting volatile in place could be a workaround, 
causing gcc to generate a saner code), but it doesn't work either:

# cat x.c
struct x {
    long a;
    volatile unsigned int lock;
    unsigned int full:1;
};

void
wrong(struct x *ptr)
{
        ptr->full = 1;
}

int main()
{
        wrong(0);
}
# gcc -O2 x.c
# gdb -q ./a.out 
Reading symbols from /root/a.out...done.
(gdb) disassemble wrong
Dump of assembler code for function wrong:
   0x40000000000005c0 <+0>:     [MMI]       adds r32=8,r32
   0x40000000000005c1 <+1>:                 nop.m 0x0
   0x40000000000005c2 <+2>:                 mov r15=1;;
   0x40000000000005d0 <+16>:    [MMI]       ld8 r14=[r32];;
   0x40000000000005d1 <+17>:                nop.m 0x0
   0x40000000000005d2 <+18>:                dep r14=r15,r14,32,1;;
   0x40000000000005e0 <+32>:    [MIB]       st8 [r32]=r14
   0x40000000000005e1 <+33>:                nop.i 0x0
   0x40000000000005e2 <+34>:                br.ret.sptk.many b0;;

In my opinion, this is a clear bug in gcc (while the original problem, 
without explitict volatile, is not a C spec violation per se, it's just 
very inconvenient :) ).

-- 
Jiri Kosina
SUSE Labs

  reply	other threads:[~2012-02-01 17:12 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-01 15:19 Memory corruption due to word sharing Jan Kara
2012-02-01 15:34 ` Markus Trippelsdorf
2012-02-01 16:37 ` Colin Walters
2012-02-01 16:56   ` Linus Torvalds
2012-02-01 17:11     ` Jiri Kosina [this message]
2012-02-01 17:37       ` Linus Torvalds
2012-02-01 17:41       ` Michael Matz
2012-02-01 18:09         ` David Miller
2012-02-01 18:45           ` Jeff Law
2012-02-01 19:09             ` Linus Torvalds
2012-02-02 15:51               ` Jeff Garzik
2012-02-01 18:57           ` Linus Torvalds
2012-02-01 19:04           ` Peter Bergner
2012-02-01 18:52         ` Linus Torvalds
2012-02-02  9:35           ` Richard Guenther
2012-02-02  9:37           ` Richard Guenther
2012-02-02 13:43           ` Michael Matz
2012-02-01 16:41 ` Linus Torvalds
2012-02-01 17:42   ` Torvald Riegel
2012-02-01 19:40     ` Jakub Jelinek
2012-02-01 20:01       ` Linus Torvalds
2012-02-01 20:16         ` Jakub Jelinek
2012-02-01 20:44           ` Linus Torvalds
2012-02-02 15:58             ` Aldy Hernandez
2012-02-02 16:28               ` Michael Matz
2012-02-02 17:51                 ` Linus Torvalds
2012-02-01 20:19         ` Linus Torvalds
2012-02-02  9:46           ` Richard Guenther
2012-02-01 19:44     ` Boehm, Hans
2012-02-01 19:54       ` Jeff Law
2012-02-01 19:47     ` Linus Torvalds
2012-02-01 19:58       ` Alan Cox
2012-02-01 20:41       ` Torvald Riegel
2012-02-01 20:59         ` Linus Torvalds
2012-02-01 21:24           ` Torvald Riegel
2012-02-01 21:55             ` Linus Torvalds
2012-02-01 21:25           ` Boehm, Hans
2012-02-01 22:27             ` Linus Torvalds
2012-02-01 22:45           ` Paul E. McKenney
2012-02-01 23:11             ` Linus Torvalds
2012-02-02 18:42               ` Paul E. McKenney
2012-02-02 19:08                 ` Linus Torvalds
2012-02-02 19:37                   ` Paul E. McKenney
2012-02-03 16:38                     ` Andrew MacLeod
2012-02-03 17:16                       ` Linus Torvalds
2012-02-03 19:16                         ` Andrew MacLeod
2012-02-03 20:00                           ` Linus Torvalds
2012-02-03 20:19                             ` Paul E. McKenney
2012-02-06 15:38                             ` Torvald Riegel
2012-02-10 19:27                             ` Richard Henderson
2012-02-02 11:19           ` Ingo Molnar
2012-02-01 21:04       ` Boehm, Hans
2012-02-02  9:28         ` Bernd Petrovitsch
2012-02-01 17:08 ` Torvald Riegel
2012-02-01 17:29   ` Linus Torvalds
2012-02-01 20:53     ` Torvald Riegel
2012-02-01 21:20       ` Linus Torvalds
2012-02-01 21:37         ` Torvald Riegel
2012-02-01 22:18           ` Boehm, Hans
2012-02-02 11:11 ` James Courtier-Dutton
2012-02-02 11:24   ` Richard Guenther
2012-02-02 11:13 ` David Sterba
2012-02-02 11:23   ` Richard Guenther
2012-02-03  6:45 ` DJ Delorie
2012-02-03  9:37   ` Richard Guenther
2012-02-03 10:03     ` Matthew Gretton-Dann
2012-02-01 17:52 Dennis Clarke

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=alpine.LRH.2.00.1202011808240.22725@twin.jikos.cz \
    --to=jkosina@suse.cz \
    --cc=dsterba@suse.cz \
    --cc=gcc@gcc.gnu.org \
    --cc=jack@suse.cz \
    --cc=linux-ia64@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ptesarik@suse.cz \
    --cc=rguenther@suse.de \
    --cc=torvalds@linux-foundation.org \
    --cc=walters@verbum.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).