Re: [RFC] Detect most integer overflows.

2014-10-23 Thread Hannes Frederic Sowa
Hi Marek,

On Do, 2014-10-23 at 10:23 +0200, Marek Polacek wrote:
> On Tue, Apr 22, 2014 at 01:58:00PM +0200, Hannes Frederic Sowa wrote:
> > I'll play around and will post a new patch in the not too distant
> > future. ;)
> 
> Are you still planning on posting the revised patch?  Perhaps I could
> take and finish the patch, but I don't think I can do that because you
> don't have a copyright assignment with FSF.

I still have it on my radar and implemented multiplication checking some
time ago.

I rebased the patch 1-2 months ago and something broke with folding but
I hadn't enough time to have a closer look.

Anyway, if you want to work on the patch that would be awesome! I can
try to resolve the missing paper work with the FSF ASAP if that blocks
you from working on it.

Bye,
Hannes




Re: [RFC] Detect most integer overflows.

2014-04-22 Thread Hannes Frederic Sowa
On Thu, Apr 17, 2014 at 04:20:06PM +0200, Ondřej Bílka wrote:
> On Sat, Apr 12, 2014 at 12:53:45AM +0200, Hannes Frederic Sowa wrote:
> > Hi!
> > 
> > On Tue, Oct 29, 2013 at 10:41:56AM +0100, Richard Biener wrote:
> > > For a "quick" GCC implementation of the builtins you could expand
> > > them to a open-coded sequence during gimplification.  But due to
> > > the issues pointed out above I'm not sure it is the best interface
> > > to support (though now the names are taken).
> > 
> > I played around with gcc internals for the first time today and came
> > up with this. As this is my first patch to gcc I am very happy to hear
> > feedback. Thanks!
> > 
> Did you looked at resulting assembly for simple expressions?

I had a look but didn't care at all at this point in time. I guess the
best way to deal with this in the end is to make the check processor
dependent to use overflow/carry flags to check if an overflow/wraparound
happend. The addv4 primitives which came in with asan might be helpful
for this.

> Also Paul Eggert suggested at another list[1] to implement these with
> 128bit arithmetic which gcc can optimize quite well, it uses overflow
> flag as check.

I thought about that but wasn't sure if 128 bit arithmetic works on all
platforms and on freestanding binaries.

> Could these builtins use a 128bit arithmetic as well?

I guess it would be possible and if it is available on all platforms I could
certainly switch to those.

> P.S.
> 
> A generated code is affected by generic gcc bug that gcc uses
> conditional move instruction even when branch is very unlikely and 
> jump would be faster.
> 
> [1] https://sourceware.org/ml/libc-alpha/2013-12/msg00084.html

Thanks for the pointer!

I'll play around and will post a new patch in the not too distant
future. ;)

Bye,

  Hannes



Re: [RFC] Detect most integer overflows.

2014-04-22 Thread Hannes Frederic Sowa
On Tue, Apr 15, 2014 at 03:41:53PM +0200, Richard Biener wrote:
> On Sat, Apr 12, 2014 at 12:53 AM, Hannes Frederic Sowa
>  wrote:
> > Hi!
> >
> > On Tue, Oct 29, 2013 at 10:41:56AM +0100, Richard Biener wrote:
> >> For a "quick" GCC implementation of the builtins you could expand
> >> them to a open-coded sequence during gimplification.  But due to
> >> the issues pointed out above I'm not sure it is the best interface
> >> to support (though now the names are taken).
> >
> > I played around with gcc internals for the first time today and came
> > up with this. As this is my first patch to gcc I am very happy to hear
> > feedback. Thanks!
> 
> Looks reasonable for a first patch to GCC!  New functions miss a
> toplevel comment and the big conditionals would benefit from a comment
> spelling out in a more readable way what is tested.

I'll do that.

> Note that you generally should use fold_buildN instead of buildN.

Thanks for the hint.

> And the patch lacks additions to gcc/doc/extend.texi documenting
> these builtins.

The patch was merely meant as a PoC to see whether the approach of
rewriting the code during gimplification is still acceptable and thus
only focused on that part. In the end I want to provide a complete patch
which adds multiplication checks and also updates the documentation.

> And then we come to the issue that a patch of this size requires a
> copyright assignment with the FSF - do you have one covering GCC work?

No, not yet, but I'll read up on it and will follow-up on that with the
relevant persons.

Thank you,

  Hannes



Re: [RFC] Detect most integer overflows.

2014-04-11 Thread Hannes Frederic Sowa
Hi!

On Tue, Oct 29, 2013 at 10:41:56AM +0100, Richard Biener wrote:
> For a "quick" GCC implementation of the builtins you could expand
> them to a open-coded sequence during gimplification.  But due to
> the issues pointed out above I'm not sure it is the best interface
> to support (though now the names are taken).

I played around with gcc internals for the first time today and came
up with this. As this is my first patch to gcc I am very happy to hear
feedback. Thanks!

diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index fba9c7d..7d01c91 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -134,7 +134,10 @@ DEF_PRIMITIVE_TYPE (BT_I8, builtin_type_for_size 
(BITS_PER_UNIT*8, 1))
 DEF_PRIMITIVE_TYPE (BT_I16, builtin_type_for_size (BITS_PER_UNIT*16, 1))
 
 DEF_POINTER_TYPE (BT_PTR_CONST_STRING, BT_CONST_STRING)
+DEF_POINTER_TYPE (BT_PTR_UINT, BT_UINT)
 DEF_POINTER_TYPE (BT_PTR_LONG, BT_LONG)
+DEF_POINTER_TYPE (BT_PTR_ULONG, BT_ULONG)
+DEF_POINTER_TYPE (BT_PTR_LONGLONG, BT_LONGLONG)
 DEF_POINTER_TYPE (BT_PTR_ULONGLONG, BT_ULONGLONG)
 DEF_POINTER_TYPE (BT_PTR_PTR, BT_PTR)
 
@@ -431,6 +434,21 @@ DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I8_INT, BT_VOID, 
BT_VOLATILE_PTR, BT_I8, BT
 DEF_FUNCTION_TYPE_3 (BT_FN_VOID_VPTR_I16_INT, BT_VOID, BT_VOLATILE_PTR, 
BT_I16, BT_INT)
 DEF_FUNCTION_TYPE_3 (BT_FN_INT_PTRPTR_SIZE_SIZE, BT_INT, BT_PTR_PTR, BT_SIZE, 
BT_SIZE)
 
+DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_INT_INT_PTR_INT, BT_BOOL, BT_INT, BT_INT,
+BT_INT_PTR)
+DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_LONG_LONG_PTR_LONG, BT_BOOL, BT_LONG, BT_LONG,
+BT_PTR_LONG)
+DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_LONGLONG_LONGLONG_PTR_LONGLONG, BT_BOOL,
+BT_LONGLONG, BT_LONGLONG, BT_PTR_LONGLONG)
+
+DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_UINT_UINT_PTR_UINT, BT_BOOL, BT_UINT, BT_UINT,
+BT_PTR_UINT)
+DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_ULONG_ULONG_PTR_ULONG, BT_BOOL, BT_ULONG, 
BT_ULONG,
+BT_PTR_ULONG)
+DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_ULONGLONG_ULONGLONG_PTR_ULONGLONG, BT_BOOL,
+BT_ULONGLONG, BT_ULONGLONG, BT_PTR_ULONGLONG)
+
+
 DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
 BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR)
 DEF_FUNCTION_TYPE_4 (BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG,
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 5a76ba3..c1f5609 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -853,6 +853,37 @@ DEF_GCC_BUILTIN (BUILT_IN_FILE, "FILE", 
BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LI
 DEF_GCC_BUILTIN (BUILT_IN_FUNCTION, "FUNCTION", BT_FN_CONST_STRING, 
ATTR_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
 
+/* overflow builtins. */
+DEF_GCC_BUILTIN (BUILT_IN_UADD_OVERFLOW, "uadd_overflow",
+BT_FN_BOOL_UINT_UINT_PTR_UINT, ATTR_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_UADDL_OVERFLOW, "uaddl_overflow",
+BT_FN_BOOL_ULONG_ULONG_PTR_ULONG, ATTR_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_UADDLL_OVERFLOW, "uaddll_overflow",
+BT_FN_BOOL_ULONGLONG_ULONGLONG_PTR_ULONGLONG,
+ATTR_NOTHROW_LEAF_LIST)
+
+DEF_GCC_BUILTIN (BUILT_IN_USUB_OVERFLOW, "usub_overflow",
+BT_FN_BOOL_UINT_UINT_PTR_UINT, ATTR_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_USUBL_OVERFLOW, "usubl_overflow",
+BT_FN_BOOL_ULONG_ULONG_PTR_ULONG, ATTR_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_USUBLL_OVERFLOW, "usubll_overflow",
+BT_FN_BOOL_ULONGLONG_ULONGLONG_PTR_ULONGLONG,
+ATTR_NOTHROW_LEAF_LIST)
+
+DEF_GCC_BUILTIN (BUILT_IN_SADD_OVERFLOW, "sadd_overflow",
+BT_FN_BOOL_INT_INT_PTR_INT, ATTR_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_SADDL_OVERFLOW, "saddl_overflow",
+BT_FN_BOOL_LONG_LONG_PTR_LONG, ATTR_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_SADDLL_OVERFLOW, "saddll_overflow",
+BT_FN_BOOL_LONGLONG_LONGLONG_PTR_LONGLONG, 
ATTR_NOTHROW_LEAF_LIST)
+
+DEF_GCC_BUILTIN (BUILT_IN_SSUB_OVERFLOW, "ssub_overflow",
+BT_FN_BOOL_INT_INT_PTR_INT, ATTR_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_SSUBL_OVERFLOW, "ssubl_overflow",
+BT_FN_BOOL_LONG_LONG_PTR_LONG, ATTR_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_SSUBLL_OVERFLOW, "ssubll_overflow",
+BT_FN_BOOL_LONGLONG_LONGLONG_PTR_LONGLONG, 
ATTR_NOTHROW_LEAF_LIST)
+
 /* Synchronization Primitives.  */
 #include "sync-builtins.def"
 
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 7441784..b4494a0 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -2224,6 +2224,138 @@ maybe_fold_stmt (gimple_stmt_iterator *gsi)
   return fold_stmt (gsi);
 }
 
+/* Is this an overflow builtin? */
+
+static bool
+builtin_overflow_p(tree fndecl)
+{
+  if (!fndecl)
+return false;
+  else if (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
+return false;
+  else
+switch (DECL_FUNCTION_CODE (

Re: Request for discussion: Rewrite of inline assembler docs

2014-03-28 Thread Hannes Frederic Sowa
On Fri, Mar 28, 2014 at 01:15:39PM +, Andrew Haley wrote:
> On 03/28/2014 10:46 AM, Hannes Frederic Sowa wrote:
> > On Fri, Mar 28, 2014 at 09:41:41AM +, Andrew Haley wrote:
> >> On 03/28/2014 09:30 AM, Hannes Frederic Sowa wrote:
> >>> On Fri, Mar 28, 2014 at 09:10:11AM +, Andrew Haley wrote:
> >>>> On 03/28/2014 06:20 AM, dw wrote:
> >>>>> Using this clobber causes the compiler to flush all (modified) 
> >>>>> registers 
> >>>>> being used to store memory-based values to memory before executing the 
> >>>>> @code{asm} statement.
> >>>>
> >>>> I don't know what a "memory-based" value is.  This phrase doesn't help
> >>>> at all.  In addition, it isn't true.  Modified registers are not
> >>>> flushed to memory unless they are clobbered or their address is taken.
> >>>> This sentence should be deleted.
> >>>
> >>> i and sum form your example are not allocated in memory. If you make
> >>> one of them static you should be able to see the effect.
> >>
> >> I know.  That's not the point.  "memory-based" is not a well-defined
> >> term.  In order to write clear documentation it is necessary either to
> >> define terms or to use terms that are already well-defined.
> > 
> > Ok, I see the problem. Maybe something like this by avoiding the term?
> > 
> > Using this clobber causes the compiler to flush all (modified) registers
> > being used to store values which gcc decided to originally allocate in
> > memory before executing the @code{asm} statement.
> 
> Not really, no: that's not true.

Hmm, ok?

> >> What is true here is that all registers used to cache variables that
> >> are reachable from pointers in the program are flushed.  Anything that
> >> is statically allocated is reachable, as is anything dynamically
> >> allocated by malloc; auto variables are not reachable unless their
> >> address is taken.
> > 
> > One would have to go into detail of various optimizations which could
> > remove the address taking
> 
> One would not: any such optimization would be incorrect.  Any memory
> reachable from an inline asm statement with a memory clobber must
> be flushed to memory.

If I extend your example with an additional pointer and take the address of s
it still doesn't allocate s in memory and as such cannot flush out the
register content, which is perfectly legal. The pointer is completley
eliminated (this is an extreme example).

int sum(int a[], int l) {
  int i;
  int s = 0;
  int *sp = &s;
  for (i = 0; i < l; i++) {
asm volatile("nop # Nothing at all":::"memory");
*sp += a[i];
  }
  return s;
}

> > e.g. IMHO the last sentence of the paragraph already
> > deals with this.
> 
> Which last sentence of what paragraph?

This one:

| For performance reasons, some variables only exist in registers and never
| get written to memory.  The "memory" clobber does not force these values
| to get written to memory.

Btw. very nice work!

Thanks,

  Hannes



Re: Request for discussion: Rewrite of inline assembler docs

2014-03-28 Thread Hannes Frederic Sowa
On Fri, Mar 28, 2014 at 03:03:11PM +, Andrew Haley wrote:
> On 03/28/2014 02:48 PM, Hannes Frederic Sowa wrote:
> > On Fri, Mar 28, 2014 at 01:15:39PM +, Andrew Haley wrote:
> >> On 03/28/2014 10:46 AM, Hannes Frederic Sowa wrote:
> >>> On Fri, Mar 28, 2014 at 09:41:41AM +, Andrew Haley wrote:
> >>>> On 03/28/2014 09:30 AM, Hannes Frederic Sowa wrote:
> >>>>> On Fri, Mar 28, 2014 at 09:10:11AM +, Andrew Haley wrote:
> >>>>>> On 03/28/2014 06:20 AM, dw wrote:
> > 
> >>>> What is true here is that all registers used to cache variables that
> >>>> are reachable from pointers in the program are flushed.  Anything that
> >>>> is statically allocated is reachable, as is anything dynamically
> >>>> allocated by malloc; auto variables are not reachable unless their
> >>>> address is taken.
> >>>
> >>> One would have to go into detail of various optimizations which could
> >>> remove the address taking
> >>
> >> One would not: any such optimization would be incorrect.  Any memory
> >> reachable from an inline asm statement with a memory clobber must
> >> be flushed to memory.
> > 
> > If I extend your example with an additional pointer and take the address of 
> > s
> > it still doesn't allocate s in memory and as such cannot flush out the
> > register content, which is perfectly legal. The pointer is completley
> > eliminated (this is an extreme example).
> > 
> > int sum(int a[], int l) {
> >   int i;
> >   int s = 0;
> >   int *sp = &s;
> >   for (i = 0; i < l; i++) {
> > asm volatile("nop # Nothing at all":::"memory");
> > *sp += a[i];
> >   }
> >   return s;
> > }
> 
> But that's not reachable from the asm.  Reachability is key here.  The
> address of s is taken, but not used; GCC knows that it is not
> reachable.
> 
> >>> e.g. IMHO the last sentence of the paragraph already
> >>> deals with this.
> >>
> >> Which last sentence of what paragraph?
> > 
> > This one:
> > 
> > | For performance reasons, some variables only exist in registers
> > | and never get written to memory.  The "memory" clobber does not
> > | force these values to get written to memory.
> 
> Except when it does; this is why the technical language has to be
> *precise*.
> 
> The memory clobber will force all reachable variables into memory: it
> must.
> 
> If we're going to avoid precise technical terms like "reachable" we
> have to find some other way of saying this, or not mention is at all.
> We must not say things that are misleading.

I guess I was confused with the term reachability, because I considered
stack values reachable regarding the inline assembler block, too.

Can one call that "symbolic reachability"? It would be great if the new
documentation could explain that, but I guess I am not the right person to
propose such a paragraph.

Bye,

  Hannes



Re: Request for discussion: Rewrite of inline assembler docs

2014-03-28 Thread Hannes Frederic Sowa
On Fri, Mar 28, 2014 at 09:41:41AM +, Andrew Haley wrote:
> On 03/28/2014 09:30 AM, Hannes Frederic Sowa wrote:
> > On Fri, Mar 28, 2014 at 09:10:11AM +, Andrew Haley wrote:
> >> On 03/28/2014 06:20 AM, dw wrote:
> >>> Using this clobber causes the compiler to flush all (modified) registers 
> >>> being used to store memory-based values to memory before executing the 
> >>> @code{asm} statement.
> >>
> >> I don't know what a "memory-based" value is.  This phrase doesn't help
> >> at all.  In addition, it isn't true.  Modified registers are not
> >> flushed to memory unless they are clobbered or their address is taken.
> >> This sentence should be deleted.
> > 
> > i and sum form your example are not allocated in memory. If you make
> > one of them static you should be able to see the effect.
> 
> I know.  That's not the point.  "memory-based" is not a well-defined
> term.  In order to write clear documentation it is necessary either to
> define terms or to use terms that are already well-defined.

Ok, I see the problem. Maybe something like this by avoiding the term?

Using this clobber causes the compiler to flush all (modified) registers
being used to store values which gcc decided to originally allocate in
memory before executing the @code{asm} statement.

> What is true here is that all registers used to cache variables that
> are reachable from pointers in the program are flushed.  Anything that
> is statically allocated is reachable, as is anything dynamically
> allocated by malloc; auto variables are not reachable unless their
> address is taken.

One would have to go into detail of various optimizations which could
remove the address taking e.g. IMHO the last sentence of the paragraph already
deals with this.

Bye,

  Hannes



Re: Request for discussion: Rewrite of inline assembler docs

2014-03-28 Thread Hannes Frederic Sowa
On Fri, Mar 28, 2014 at 09:10:11AM +, Andrew Haley wrote:
> On 03/28/2014 06:20 AM, dw wrote:
> > Using this clobber causes the compiler to flush all (modified) registers 
> > being used to store memory-based values to memory before executing the 
> > @code{asm} statement.
> 
> I don't know what a "memory-based" value is.  This phrase doesn't help
> at all.  In addition, it isn't true.  Modified registers are not
> flushed to memory unless they are clobbered or their address is taken.
> This sentence should be deleted.

i and sum form your example are not allocated in memory. If you make
one of them static you should be able to see the effect.

Bye,

  Hannes



Re: linux says it is a bug

2014-03-04 Thread Hannes Frederic Sowa
On Tue, Mar 04, 2014 at 12:08:19PM +0100, Richard Biener wrote:
> On Tue, Mar 4, 2014 at 10:33 AM, Hannes Frederic Sowa
>  wrote:
> > On Tue, Mar 04, 2014 at 09:26:31AM +, Andrew Haley wrote:
> >> On 03/04/2014 09:24 AM, Hannes Frederic Sowa wrote:
> >> >> > So the bug was probably fixed more than 15 years ago.
> >> > Probably :)
> >> >
> >> > But the __volatile__ shoud do no harm and shouldn't influence code
> >> > generation in any way, no?
> >>
> >> Of course it will: it's a barrier.
> >
> > Sure. My question was about the volatile marker. asm("":::"memory") should 
> > act
> > as the barrier alone.
> 
> __asm__("":::"memory")
> 
> is a memory barrier
> 
> volatile __asm__("":::"memory")
> 
> is a memory barrier and a barrier for other volatile instructions.
> 
> Nothing more, nothing less.
> 
> Neither is a "optimization barrier" or "compiler barrier" or whatever
> name you invent.

Being a bit more familiar with the kernel code I often think about a
memory barrier as "fencing" instruction.

Thanks for the clarification,

  Hannes



Re: linux says it is a bug

2014-03-04 Thread Hannes Frederic Sowa
On Tue, Mar 04, 2014 at 09:26:31AM +, Andrew Haley wrote:
> On 03/04/2014 09:24 AM, Hannes Frederic Sowa wrote:
> >> > So the bug was probably fixed more than 15 years ago.
> > Probably :)
> > 
> > But the __volatile__ shoud do no harm and shouldn't influence code
> > generation in any way, no?
> 
> Of course it will: it's a barrier.

Sure. My question was about the volatile marker. asm("":::"memory") should act
as the barrier alone.



Re: linux says it is a bug

2014-03-04 Thread Hannes Frederic Sowa
On Tue, Mar 04, 2014 at 09:19:40AM +, Jonathan Wakely wrote:
> On 4 March 2014 09:17, Hannes Frederic Sowa  
> wrote:
> > On Tue, Mar 04, 2014 at 10:10:21AM +0100, Richard Biener wrote:
> >> On Tue, Mar 4, 2014 at 7:40 AM, lin zuojian  wrote:
> >> > Hi,
> >> > in include/linux/compiler-gcc.h :
> >> >
> >> > /* Optimization barrier */
> >> > /* The "volatile" is due to gcc bugs */
> >> > #define barrier() __asm__ __volatile__("": : :"memory")
> >> >
> >> > The comment of Linux says this is a gcc bug.But will any sane compiler
> >> > disable optimization without "volatile" key word?
> >>
> >> Depends what they call an "optimization barrier".  A plain
> >> __asm__ ("" : : : "memory") is a memory barrier.  Adding volatile
> >> to the asm makes it a barrier for every other volatile instruction,
> >> nothing more.
> >
> > This is meant to be a compiler barrier not a memory barrier and got
> > added by David Miller because of a problem in gcc-2.7.2:
> >
> > | Add __volatile__ to barrier() definition, I convinced Linus
> > | to eat this patch.  The problem is that with gcc-2.7.2 derived
> > | compilers the instruction scheduler can move it around due to
> > | a bug.  This bug appears on sparc64/SMP with our old compiler
> > | in that is miscompiles the beginning of exit.c:release() causing
> > | lockups if the race is hit in the SMP specific code there.  I
> > | believe sparc32 gcc-2.7.2 sees this bug too, but I'm not too sure
> > | (Anton showed me something similar once).
> 
> 
> 
> So the bug was probably fixed more than 15 years ago.

Probably :)

But the __volatile__ shoud do no harm and shouldn't influence code
generation in any way, no?




Re: linux says it is a bug

2014-03-04 Thread Hannes Frederic Sowa
On Tue, Mar 04, 2014 at 10:10:21AM +0100, Richard Biener wrote:
> On Tue, Mar 4, 2014 at 7:40 AM, lin zuojian  wrote:
> > Hi,
> > in include/linux/compiler-gcc.h :
> >
> > /* Optimization barrier */
> > /* The "volatile" is due to gcc bugs */
> > #define barrier() __asm__ __volatile__("": : :"memory")
> >
> > The comment of Linux says this is a gcc bug.But will any sane compiler
> > disable optimization without "volatile" key word?
> 
> Depends what they call an "optimization barrier".  A plain
> __asm__ ("" : : : "memory") is a memory barrier.  Adding volatile
> to the asm makes it a barrier for every other volatile instruction,
> nothing more.

This is meant to be a compiler barrier not a memory barrier and got
added by David Miller because of a problem in gcc-2.7.2:

| Add __volatile__ to barrier() definition, I convinced Linus
| to eat this patch.  The problem is that with gcc-2.7.2 derived
| compilers the instruction scheduler can move it around due to
| a bug.  This bug appears on sparc64/SMP with our old compiler
| in that is miscompiles the beginning of exit.c:release() causing
| lockups if the race is hit in the SMP specific code there.  I
| believe sparc32 gcc-2.7.2 sees this bug too, but I'm not too sure
| (Anton showed me something similar once).

Greetings,

  Hannes



Re: [RFC] Detect most integer overflows.

2013-10-26 Thread Hannes Frederic Sowa
On Sat, Oct 26, 2013 at 09:29:12PM +0200, Ondřej Bílka wrote:
> Hi, as I brainstormed how prevent possible overflows in memory allocation I
> came with heretic idea:
> 
> For gcc -D_FORTIFY_SOURCE=2 we expand all multiplication with size_t
> type by one that checks for integer overflow and aborts on it. This
> would prevent most overflow at cost of breaking some legitimate
> applications that use multiplication in clever way.
> 
> A less heretic way that is applicable for C++ would be write a class
> size_t overflow that would do arithmetic in saturating way and issue
> warnings when there is a size_t multiplication.

I am afraid of the false-positive aborts which could result in DoS against
applications. I like the checked arithmetic builtins LLVM introduced in
3.4 (not yet released) where one can test for overflow manually and handle
the overflows appropriately. They also generate better code (e.g. they
use the overflow flag and get inlined on x86 compared to the ftrapv insn).

So I would vote for fast checked arithmetic builtins first.

Greetings,

  Hannes



possible deprecation of walk_use_def_chains?

2013-09-26 Thread Hannes Frederic Sowa
Hello!

Because the last user of walk_use_def_chains vanished in revision r171352
(removal of ipa-struct-reorg) I wondered if this function is pending
deprecation or removal in upcoming gcc versions?

Thanks,

  Hannes



Re: [oss-security] PoC: Function Pointer Protection in C Programs

2013-08-21 Thread Hannes Frederic Sowa
Hi!

On Wed, Aug 21, 2013 at 04:43:13PM +0200, Stephen Röttger wrote:
> Approach:
> The basic idea of the thesis is to record all addresses that are
> assigned to a function pointer variable at some place in the program (or
> in one of the shared libraries) and if a function pointer is called,
> verify that the address has been recorded previously. Thus, if an
> attacker overwrites the fp variable with either the address of system()
> or of a stack pivoting gadget, the fp call will fail, since these
> adresses have never been assigned to a function pointer in the program.
> The security of the approach relies on the assumption that no function
> that can be abused for malicious purposes is ever assigned to a function
> pointer, but this requirement will be weakened under future work.
> 
> How this works:
> The compiler, GCC in my PoC, will register all assignments of function
> pointer variables in the source code and will create a global variable
> for the assigned function, which is initialized to the function's
> address. Then, it replaces the address of the function in the assignment
> with the address of the newly created variable:
> fp f = &printf;
> becomes:
>   printf_var = &printf;
> ...
> fp f = &printf_var;
> Further, a global constructor is created that is run before the main
> function of the program or before the shared library is loaded. This
> constructor allocates a memory area where it stores the address of each
> fp address previously registered. The created global variable is then
> overwritten to point to the new memory area instead. Finally, the memory
> area is mapped read only. Also, the variable where the address of this
> area is stored has to be in read only memory as well to prevent
> malicious overwrites. Putting it all together, the memory layout looks
> like this:
> 
>  +---++++--++--+
>  | fp f  | -> | printf_var | -> | protected memory | -> | printf() |
>  +---++++--++--+
> Additional instructions are emitted by the compiler before function
> pointer calls. They will verify that the global variable (printf_var)
> points to the protected memory region, from which it extracts the real
> function pointer to be called. If an attacker is able to overwrite
> either the function pointer or the global variable, he will only be able
> to execute functions contained in the protected memory area (which he
> can't overwrite since it is mapped read only during normal execution).

Thanks for doing research in this area! :)

Your approach seems to have some slight similarities with -fvtable-verify:


Maybe some code sharing could be achieved?

Greetings,

  Hannes