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]
Date:	Tue, 17 Aug 2010 18:31:50 -0700
From:	Linus Torvalds <torvalds@...ux-foundation.org>
To:	David Miller <davem@...emloft.net>
Cc:	akpm@...ux-foundation.org, sparclinux@...r.kernel.org,
	linux-kernel@...r.kernel.org
Subject: Re: [GIT] Sparc

On Tue, Aug 17, 2010 at 6:03 PM, David Miller <davem@...emloft.net> wrote:
>
> Among other things, this fixes the rwsem signedness issue we
> were discussing earlier today.

Your commit message is missing the C rules for hex constants. It says

  "hex constants are unsigned unless explicitly casted or negated."

and that's not true.

The rule is that hex constants are signed _except_ if they don't fit
in a signed.

So with a 32-bit 'int', 0x123 is signed, but 0x80000000 is unsigned.

So the reason (-0x00010000) is signed is _not_ because of the
negation, but simply because 0x00010000 fits in a signed int. So for
example, the constant (-0xf0000000) is still unsigned, despite the
negation.

So to make something signed, you need to either cast it, make sure it
fits in a signed int, use the 'l' postfix (which also makes it long,
of course), or use a decimal representation. So

   #define X 4294901760

is a _signed_ constant with same value as 0xffff0000 (but it's "signed
long", because the rules for decimal numbers and hex numbers are
different: a decimal number is always signed and because it doesn't
fit in 'int' it will extend to 'long'. A hex number is first done as
unsigned, and only extended to long if it doesn't fit in that.

To make things _really_ confused, sometimes the types actually depend
on whether you're compiling with the c90 standards. A decimal constant
is _always_ signed in traditional C - it goes from 'int' to 'long',
and stays 'long' even if it doesn't fit (ie with a 32-bit long,
2147483648 is of type 'long' even though it doesn't fit in 'long' and
is negative). But in c90, it does from 'int' to 'long' to 'unsigned
long'.

Or maybe it was the other way around. I forget.

Confused yet?

The basic rule becomes: never _ever_ overflow 'int' in a constant,
without specifying the exact type you want. That way you avoid all the
subtle cases.

                     Linus
--
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