All of lore.kernel.org
 help / color / mirror / Atom feed
* Compat sysinfo syscall (kernel/sys.c) relying on undefined behavior?
@ 2014-09-02 20:35 Scotty Bauer
  2014-09-03  7:13 ` Clemens Ladisch
  0 siblings, 1 reply; 2+ messages in thread
From: Scotty Bauer @ 2014-09-02 20:35 UTC (permalink / raw)
  To: linux-kernel

 am getting acquainted with the linux kernel and to do so I've been browsing the source.


In the compat version of sysinfo, kernel/sys.c we see the following:

COMPAT_SYSCALL_DEFINE1(sysinfo, struct compat_sysinfo __user *, info)
{
    struct sysinfo s;

    do_sysinfo(&s);

    /* Check to see if any memory value is too large for 32-bit and scale
     *  down if needed
     */
    if ((s.totalram >> 32) || (s.totalswap >> 32)) {
        int bitcount = 0;

...


s.totalram is a u32, and the standard says:
"If the value of the right operand is negative or is greater than or equal to the width 
of the promoted left operand, the behavior is undefined."

Is there some promotion, compiler flag, something obvious that I am missing, or is this a 
problem?


Best,
Scotty


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Compat sysinfo syscall (kernel/sys.c) relying on undefined behavior?
  2014-09-02 20:35 Compat sysinfo syscall (kernel/sys.c) relying on undefined behavior? Scotty Bauer
@ 2014-09-03  7:13 ` Clemens Ladisch
  0 siblings, 0 replies; 2+ messages in thread
From: Clemens Ladisch @ 2014-09-03  7:13 UTC (permalink / raw)
  To: Scotty Bauer, linux-kernel

Scotty Bauer wrote:
> In the compat version of sysinfo, kernel/sys.c we see the following:
>
>     /* Check to see if any memory value is too large for 32-bit and scale
>      *  down if needed
>      */
>     if ((s.totalram >> 32) || (s.totalswap >> 32)) {

This code is supposed to check if any of the bits in the upper half of
these 64-bit values are set.

> s.totalram is a u32

Oops.

> the behavior is undefined.

For a constant shift amount, gcc happens to generate correct code, i.e.,
the result is zero.  (If the shift amount were not a constant, x86
processors would use only its lowest five bits, and the result would be
wrong.)

Anyway, it's not a good idea to rely on gcc's implementation of this
undefined behaviour; the code should have used upper_32_bits() instead.
Please write a patch.


Regards,
Clemens

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-09-03  7:13 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-02 20:35 Compat sysinfo syscall (kernel/sys.c) relying on undefined behavior? Scotty Bauer
2014-09-03  7:13 ` Clemens Ladisch

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.