This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug stdio/15929] New: scanf doesn't set errno to ERANGE for unsigned short overflows
- From: "filipe at codinghighway dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sourceware dot org
- Date: Wed, 04 Sep 2013 11:55:07 +0000
- Subject: [Bug stdio/15929] New: scanf doesn't set errno to ERANGE for unsigned short overflows
- Auto-submitted: auto-generated
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.