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: <200905260737.32860.lkml@morethan.org>
Date:	Tue, 26 May 2009 07:37:30 -0500
From:	"Michael S. Zick" <lkml@...ethan.org>
To:	"H. Peter Anvin" <hpa@...or.com>
Cc:	Harald Welte <HaraldWelte@...tech.com>,
	Ingo Molnar <mingo@...e.hu>,
	Thomas Gleixner <tglx@...utronix.de>,
	linux-kernel@...r.kernel.org, Alan Cox <alan@...rguk.ukuu.org.uk>
Subject: Re: [BUG FIX] Make x86_32 uni-processor Atomic ops, Atomic

On Mon May 25 2009, H. Peter Anvin wrote:
> Michael S. Zick wrote:
> > 
> > Load Effective Address does two's complement arithmetic?
> > I'll take your word for it.
> > 
> 
> LEA, and all other address calculations use 2's-complement arithmetic:
> 
> 	leal -1(%ebx),%eax
> 	leal 0xffffffff(%ebx),%eax
> 
> ... is the same instruction.
> 
> However, gcc has been known to optimize out range checks when operating
> on signed integers; it is allowed to do this by the C standard, but it
> can give surprising results if the user expected wraparound.
>

Well, it isn't a range check - - but this illustrates where my (false)
concern came from: 

Given this input file:
extern int diff_umask(int mask, int *cnt1, int *cnt2)
{ return (((mask - *cnt1) + *cnt2) & mask); }

Doing:
gcc -O2 -S -fomit-frame-pointer difftest.c

Yields (as difftest.s):
        .file   "difftest.c"
        .text
        .p2align 4,,15
.globl diff_umask
        .type   diff_umask, @function
diff_umask:
        movl    12(%esp), %eax
        movl    4(%esp), %ecx
        movl    (%eax), %edx
        leal    (%ecx,%edx), %eax
        movl    8(%esp), %edx
        subl    (%edx), %eax
        andl    %ecx, %eax
        ret
        .size   diff_umask, .-diff_umask
        .ident  "GCC: (Debian 4.3.2-1.1) 4.3.2"
        .section        .note.GNU-stack,"",@progbits

How follow that up with the commands:
gcc -O2 -c -fomit-frame-pointer difftest.s

Then examine the result with objdump:
objdump -d difftest.o

In relevant part, yields:
difftest.o:     file format elf32-i386

Disassembly of section .text:

00000000 <diff_umask>:
   0:   8b 44 24 0c             mov    0xc(%esp),%eax
   4:   8b 4c 24 04             mov    0x4(%esp),%ecx
   8:   8b 10                   mov    (%eax),%edx
   a:   8d 04 11                lea    (%ecx,%edx,1),%eax
   d:   8b 54 24 08             mov    0x8(%esp),%edx
  11:   2b 02                   sub    (%edx),%eax
  13:   21 c8                   and    %ecx,%eax
  15:   c3                      ret

= = = =

Checking the byte string 0x8d, 0x04, 0x11 against the Intel
documentation shows that the disassembly output of objdump
is incorrect - that bit string does not have an offset field.
That is the byte encoding for the gcc assembly input.

What's a person to do when the tool-chain lies?

Mike
> 	-hpa
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ