public inbox for glibc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug stdio/15929] New: scanf doesn't set errno to ERANGE for unsigned short overflows
@ 2013-09-04 11:55 filipe at codinghighway dot com
  2013-09-04 12:42 ` [Bug stdio/15929] " schwab@linux-m68k.org
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: filipe at codinghighway dot com @ 2013-09-04 11:55 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=15929

            Bug ID: 15929
           Summary: scanf doesn't set errno to ERANGE for unsigned short
                    overflows
           Product: glibc
           Version: 2.18
            Status: NEW
          Severity: normal
          Priority: P2
         Component: stdio
          Assignee: unassigned at sourceware dot org
          Reporter: filipe at codinghighway dot com

Created attachment 7186
  --> https://sourceware.org/bugzilla/attachment.cgi?id=7186&action=edit
Sample code that is able to reproduce the bug

Overview:
When scanf is called with %hu to parse an unsigned short from input, ERANGE is
not being set for values that do not fit inside an unsigned short. 

Steps to reproduce:
Compile the attached program. Run the program and try entering different
values. On a machine with 16-bit shorts, entering a number that a short can't
store, like 70000, will not trigger errno to be set to ERANGE.

Actual results:
errno is not set to ERANGE. The value read wraps around and there's no way for
the caller to know if there has been an overflow. In a system with n-bit
shorts, if number x is read, the actual value stored is x%(2^n) (it wraps
around).

Expected results:
errno should have been set to ERANGE.

Build date & hardware:
Tested with debian's built-in glibc 2.13, and also with the latest version,
2.18, compiled from official source.
filipe@debian:~/glibc-build$ uname -a
Linux debian 3.2.0-4-486 #1 Debian 3.2.46-1 i686 GNU/Linux

Additional information:
I happened to notice that errno is correctly set if the value entered is
greater than INT_MAX. So, apparently, it looks like scanf ignores the fact that
it is given a pointer to unsigned short, treating it as pointer to int instead.
Thus, every value between USHRT_MAX and INT_MAX is assumed to fit into a short.
Here's an example in my system:
$ ./bug
Enter a number: 65535
You entered 65535
Enter a number: 65536
You entered 0
Enter a number: 2000000
You entered 33920
Enter a number: 2000000000000000000000000000000000000000000000000
Value is too large, try again.
Enter a number:

-- 
You are receiving this mail because:
You are on the CC list for the bug.


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

* [Bug stdio/15929] scanf doesn't set errno to ERANGE for unsigned short overflows
  2013-09-04 11:55 [Bug stdio/15929] New: scanf doesn't set errno to ERANGE for unsigned short overflows filipe at codinghighway dot com
@ 2013-09-04 12:42 ` schwab@linux-m68k.org
  2013-09-04 13:59 ` filipe at codinghighway dot com
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: schwab@linux-m68k.org @ 2013-09-04 12:42 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=15929

--- Comment #1 from Andreas Schwab <schwab@linux-m68k.org> ---
POSIX does not specify ERANGE for fscanf.  The ERANGE error comes from strtoul
which checks against ULONG_MAX (not UINT_MAX).  If you want to do range
checking you have to do it yourself.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


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

* [Bug stdio/15929] scanf doesn't set errno to ERANGE for unsigned short overflows
  2013-09-04 11:55 [Bug stdio/15929] New: scanf doesn't set errno to ERANGE for unsigned short overflows filipe at codinghighway dot com
  2013-09-04 12:42 ` [Bug stdio/15929] " schwab@linux-m68k.org
@ 2013-09-04 13:59 ` filipe at codinghighway dot com
  2013-09-04 20:32 ` schwab@linux-m68k.org
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: filipe at codinghighway dot com @ 2013-09-04 13:59 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=15929

--- Comment #2 from Filipe Gonçalves <filipe at codinghighway dot com> ---
(In reply to Andreas Schwab from comment #1)
> POSIX does not specify ERANGE for fscanf.  The ERANGE error comes from
> strtoul which checks against ULONG_MAX (not UINT_MAX).  If you want to do
> range checking you have to do it yourself.

Well, the manpage contradicts itself, it mentions that ERANGE is used when "The
result of an integer conversion would exceed the size that can be stored in the
corresponding integer type.", but later on it says that the standards to which
it conforms to do not mention ERANGE. What do we have then?

If I call scanf, I can't do range checking, by the time it returns, how am I
supposed to know if there was an overflow?

If ERANGE is not mentioned in the standards and that serves as an excuse on why
scanf doesn't deal with it properly, then it might be better to remove that
from the "ERRORS" section, otherwise, we have an awkward situation here, where
it kind of works, but when it doesn't, it's not a bug because the standard
doesn't mention it.

But ok then, I'll just code my own function to read an unsigned short and
forget that scanf exists.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
>From glibc-bugs-return-19493-listarch-glibc-bugs=sources.redhat.com@sourceware.org Wed Sep 04 17:05:29 2013
Return-Path: <glibc-bugs-return-19493-listarch-glibc-bugs=sources.redhat.com@sourceware.org>
Delivered-To: listarch-glibc-bugs@sources.redhat.com
Received: (qmail 19714 invoked by alias); 4 Sep 2013 17:05:29 -0000
Mailing-List: contact glibc-bugs-help@sourceware.org; run by ezmlm
Precedence: bulk
List-Id: <glibc-bugs.sourceware.org>
List-Subscribe: <mailto:glibc-bugs-subscribe@sourceware.org>
List-Post: <mailto:glibc-bugs@sourceware.org>
List-Help: <mailto:glibc-bugs-help@sourceware.org>, <http://sourceware.org/lists.html#faqs>
Sender: glibc-bugs-owner@sourceware.org
Delivered-To: mailing list glibc-bugs@sourceware.org
Received: (qmail 19677 invoked by uid 48); 4 Sep 2013 17:05:24 -0000
From: "pchang9 at cs dot wisc.edu" <sourceware-bugzilla@sourceware.org>
To: glibc-bugs@sourceware.org
Subject: [Bug libc/15931] New: memcpy() has different behavior when statically linked (x86_64)
Date: Wed, 04 Sep 2013 17:05:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: new
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: glibc
X-Bugzilla-Component: libc
X-Bugzilla-Version: 2.18
X-Bugzilla-Keywords:
X-Bugzilla-Severity: normal
X-Bugzilla-Who: pchang9 at cs dot wisc.edu
X-Bugzilla-Status: NEW
X-Bugzilla-Priority: P2
X-Bugzilla-Assigned-To: unassigned at sourceware dot org
X-Bugzilla-Target-Milestone: ---
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter cc
Message-ID: <bug-15931-131@http.sourceware.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
X-Bugzilla-URL: http://sourceware.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2013-09/txt/msg00033.txt.bz2
Content-length: 1950

https://sourceware.org/bugzilla/show_bug.cgi?id\x15931

            Bug ID: 15931
           Summary: memcpy() has different behavior when statically linked
                    (x86_64)
           Product: glibc
           Version: 2.18
            Status: NEW
          Severity: normal
          Priority: P2
         Component: libc
          Assignee: unassigned at sourceware dot org
          Reporter: pchang9 at cs dot wisc.edu
                CC: drepper.fsp at gmail dot com

Hi,

In latest git commit a442b23, I notice memcpy() has different behavior
when statically linked on x86_64. Specifically, the test program has three
character arrays "a", "b" and "c". It copies the whole "b" to "a" by memcpy()
and prints the last element of "b" before exiting. Before the memcpy(),
I intentionally set the x86 DF flag by "std" instruction. When dynamically
linked with x86_64 multiarch library, it works correctly.


  pcchang@T420 ~/glibc_bug $ cat test.c
  #include <stdio.h>
  #include <string.h>

  void main(void) {
    char a[65536];
    char b[] = { [0 ... 65535] = 'b'};
    char c[] = { [0 ... 65535] = 'c'};
    printf("b[65535] before memcpy(): %c\n", b[65535]);
    asm volatile ("std");
    memcpy(a, b, sizeof(a));
    printf("b[65535] after memcpy(): %c\n", b[65535]);
  }
  pcchang@T420 ~/glibc_bug $ gcc -O0 -ggdb test.c -o test
  pcchang@T420 ~/glibc_bug $ ./test
  b[65535] before memcpy(): b
  b[65535] after memcpy(): b
  pcchang@T420 ~/glibc_bug $


However, when statically linked, the content of array "b" changes.

  pcchang@T420 ~/glibc_bug $ gcc -O0 -ggdb test.c -o test -static
  pcchang@T420 ~/glibc_bug $ ./test
  b[65535] before memcpy(): b
  b[65535] after memcpy(): c
  pcchang@T420 ~/glibc_bug $

The problem seems to be the "movsq" in sysdeps/x86_64/memcpy.S after label
"L(fast)", which implicitly assumes the DF flag is clear.

--
You are receiving this mail because:
You are on the CC list for the bug.


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

* [Bug stdio/15929] scanf doesn't set errno to ERANGE for unsigned short overflows
  2013-09-04 11:55 [Bug stdio/15929] New: scanf doesn't set errno to ERANGE for unsigned short overflows filipe at codinghighway dot com
  2013-09-04 12:42 ` [Bug stdio/15929] " schwab@linux-m68k.org
  2013-09-04 13:59 ` filipe at codinghighway dot com
@ 2013-09-04 20:32 ` schwab@linux-m68k.org
  2013-09-06  6:15 ` carlos at redhat dot com
  2014-06-13 12:57 ` fweimer at redhat dot com
  4 siblings, 0 replies; 6+ messages in thread
From: schwab@linux-m68k.org @ 2013-09-04 20:32 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=15929

--- Comment #3 from Andreas Schwab <schwab@linux-m68k.org> ---
There are no manpages as part of glibc, you should report this to the provider
of them (probably the man-pages project).

scanf is really only useful for very simple interaction.  If you want more
sophisticated behaviour you need to parse the input yourself.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


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

* [Bug stdio/15929] scanf doesn't set errno to ERANGE for unsigned short overflows
  2013-09-04 11:55 [Bug stdio/15929] New: scanf doesn't set errno to ERANGE for unsigned short overflows filipe at codinghighway dot com
                   ` (2 preceding siblings ...)
  2013-09-04 20:32 ` schwab@linux-m68k.org
@ 2013-09-06  6:15 ` carlos at redhat dot com
  2014-06-13 12:57 ` fweimer at redhat dot com
  4 siblings, 0 replies; 6+ messages in thread
From: carlos at redhat dot com @ 2013-09-06  6:15 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=15929

Carlos O'Donell <carlos at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |carlos at redhat dot com
         Resolution|---                         |INVALID

--- Comment #4 from Carlos O'Donell <carlos at redhat dot com> ---
Closing this as invalid since the code and manual are correct. Changes to the
POSIX standard need to go through the Austin Group.

Please note that manual pages, likely the Linux kernel manual pages, are not
the canonical source of documentation for glibc.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


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

* [Bug stdio/15929] scanf doesn't set errno to ERANGE for unsigned short overflows
  2013-09-04 11:55 [Bug stdio/15929] New: scanf doesn't set errno to ERANGE for unsigned short overflows filipe at codinghighway dot com
                   ` (3 preceding siblings ...)
  2013-09-06  6:15 ` carlos at redhat dot com
@ 2014-06-13 12:57 ` fweimer at redhat dot com
  4 siblings, 0 replies; 6+ messages in thread
From: fweimer at redhat dot com @ 2014-06-13 12:57 UTC (permalink / raw)
  To: glibc-bugs

https://sourceware.org/bugzilla/show_bug.cgi?id=15929

Florian Weimer <fweimer at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
              Flags|                            |security-

-- 
You are receiving this mail because:
You are on the CC list for the bug.


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

end of thread, other threads:[~2014-06-13 12:57 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-09-04 11:55 [Bug stdio/15929] New: scanf doesn't set errno to ERANGE for unsigned short overflows filipe at codinghighway dot com
2013-09-04 12:42 ` [Bug stdio/15929] " schwab@linux-m68k.org
2013-09-04 13:59 ` filipe at codinghighway dot com
2013-09-04 20:32 ` schwab@linux-m68k.org
2013-09-06  6:15 ` carlos at redhat dot com
2014-06-13 12:57 ` fweimer at redhat dot com

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 read-only IMAP folder(s) and NNTP newsgroup(s).