bug-autoconf
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

portability note about 'printf'


From: Bruno Haible
Subject: portability note about 'printf'
Date: Tue, 24 Apr 2007 00:40:30 +0200
User-agent: KMail/1.5.4

The autoconf manual mentions two portability problem of the 'printf' command.
But there is a third one: a buffer overflow that crashes /bin/printf of
Solaris 9 and Solaris 10. Example (originally reported by
Arto C. Nirkko <address@hidden>):

$ /bin/printf '%010000x' 123  
Segmentation fault
$ truss -u libc /bin/printf '%010000x' 123  
execve("/usr/bin/printf", 0xFFBFF20C, 0xFFBFF21C)  argc = 3
resolvepath("/usr/bin/printf", "/usr/bin/printf", 1023) = 15
resolvepath("/usr/lib/ld.so.1", "/usr/lib/ld.so.1", 1023) = 16
stat("/usr/bin/printf", 0xFFBFEFE0)             = 0
open("/var/ld/ld.config", O_RDONLY)             Err#2 ENOENT
stat("/usr/lib/libgen.so.1", 0xFFBFEAE8)        = 0
resolvepath("/usr/lib/libgen.so.1", "/usr/lib/libgen.so.1", 1023) = 20
open("/usr/lib/libgen.so.1", O_RDONLY)          = 3
mmap(0x00010000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_ALIGN, 3, 0) = 
0xFF3A0000
mmap(0x00010000, 98304, PROT_NONE, 
MAP_PRIVATE|MAP_NORESERVE|MAP_ANON|MAP_ALIGN, -1, 0) = 0xFF380000
mmap(0xFF380000, 22677, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 
0xFF380000
mmap(0xFF396000, 2343, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 
3, 24576) = 0xFF396000
munmap(0xFF386000, 65536)                       = 0
memcntl(0xFF380000, 6304, MC_ADVISE, MADV_WILLNEED, 0, 0) = 0
close(3)                                        = 0
stat("/usr/lib/libc.so.1", 0xFFBFEAE8)          = 0
resolvepath("/usr/lib/libc.so.1", "/usr/lib/libc.so.1", 1023) = 18
open("/usr/lib/libc.so.1", O_RDONLY)            = 3
mmap(0xFF3A0000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 
0xFF3A0000
mmap(0x00010000, 794624, PROT_NONE, 
MAP_PRIVATE|MAP_NORESERVE|MAP_ANON|MAP_ALIGN, -1, 0) = 0xFF280000
mmap(0xFF280000, 688972, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 
0xFF280000
mmap(0xFF33A000, 24000, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 
3, 696320) = 0xFF33A000
mmap(0xFF340000, 6304, PROT_READ|PROT_WRITE|PROT_EXEC, 
MAP_PRIVATE|MAP_FIXED|MAP_ANON, -1, 0) = 0xFF340000
munmap(0xFF32A000, 65536)                       = 0
memcntl(0xFF280000, 115592, MC_ADVISE, MADV_WILLNEED, 0, 0) = 0
close(3)                                        = 0
stat("/usr/lib/libdl.so.1", 0xFFBFEAE8)         = 0
resolvepath("/usr/lib/libdl.so.1", "/usr/lib/libdl.so.1", 1023) = 19
open("/usr/lib/libdl.so.1", O_RDONLY)           = 3
mmap(0xFF3A0000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 
0xFF3A0000
mmap(0x00002000, 8192, PROT_NONE, MAP_PRIVATE|MAP_NORESERVE|MAP_ANON|MAP_ALIGN, 
-1, 0) = 0xFF3FA000
mmap(0xFF3FA000, 1894, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 
3, 0) = 0xFF3FA000
close(3)                                        = 0
stat("/usr/platform/SUNW,Sun-Fire-280R/lib/libc_psr.so.1", 0xFFBFE8D8) = 0
resolvepath("/usr/platform/SUNW,Sun-Fire-280R/lib/libc_psr.so.1", 
"/usr/platform/sun4u-us3/lib/libc_psr.so.1", 1023) = 41
open("/usr/platform/SUNW,Sun-Fire-280R/lib/libc_psr.so.1", O_RDONLY) = 3
mmap(0xFF3A0000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 
0xFF3A0000
close(3)                                        = 0
mmap(0x00000000, 8192, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANON, 
-1, 0) = 0xFF370000
-> libc:atexit(0xff3bfaac, 0x22800, 0x0, 0x0)
<- libc:atexit() = 0
-> libc:atexit(0x12424, 0x22800, 0x0, 0x0)
<- libc:atexit() = 0
-> libc:setlocale(0x6, 0x124ac, 0x0, 0x0)
<- libc:setlocale() = 0xff325e8e
-> libc:textdomain(0x124b0, 0x124ac, 0x0, 0x0)
brk(0x00022CB8)                                 = 0
brk(0x00024CB8)                                 = 0
<- libc:textdomain() = 0x234d0
-> libc:strcmp(0xffbff418, 0x124c0, 0x0, 0x0)
<- libc:strcmp() = -8
-> libc:strlen(0xffbff418, 0x124c4, 0x0, 0x0)
<- libc:strlen() = 8
-> libc:malloc(0x801, 0xffbff424, 0x313233, 0x7efefeff)
<- libc:malloc() = 0x23ad0
-> libc:malloc(0x801, 0xffbff424, 0x313233, 0x7efefeff)
<- libc:malloc() = 0x242e0
-> libc:strdup(0xffbff418, 0x0, 0x0, 0x0)
<- libc:strdup() = 0x234e8
-> libc:mbtowc(0xffbff134, 0xffbff418, 0x1, 0x0)
-> libc:__mbtowc_sb(0xff33f728, 0xffbff134, 0xffbff418, 0x1)
<- libc:mbtowc() = 1
-> libc:wctomb(0x234e8, 0x25, 0xffbff418, 0x1)
-> libc:__wctomb_sb(0xff33f728, 0x234e8, 0x25, 0x1)
<- libc:wctomb() = 1
-> libc:mbtowc(0xffbff134, 0xffbff419, 0x1, 0x1)
-> libc:__mbtowc_sb(0xff33f728, 0xffbff134, 0xffbff419, 0x1)
<- libc:mbtowc() = 1
-> libc:wctomb(0x234e9, 0x30, 0xffbff419, 0x1)
-> libc:__wctomb_sb(0xff33f728, 0x234e9, 0x30, 0x1)
<- libc:wctomb() = 1
-> libc:mbtowc(0xffbff134, 0xffbff41a, 0x1, 0x1)
-> libc:__mbtowc_sb(0xff33f728, 0xffbff134, 0xffbff41a, 0x1)
<- libc:mbtowc() = 1
-> libc:wctomb(0x234ea, 0x31, 0xffbff41a, 0x1)
-> libc:__wctomb_sb(0xff33f728, 0x234ea, 0x31, 0x1)
<- libc:wctomb() = 1
-> libc:mbtowc(0xffbff134, 0xffbff41b, 0x1, 0x1)
-> libc:__mbtowc_sb(0xff33f728, 0xffbff134, 0xffbff41b, 0x1)
<- libc:mbtowc() = 1
-> libc:wctomb(0x234eb, 0x30, 0xffbff41b, 0x1)
-> libc:__wctomb_sb(0xff33f728, 0x234eb, 0x30, 0x1)
<- libc:wctomb() = 1
-> libc:mbtowc(0xffbff134, 0xffbff41c, 0x1, 0x1)
-> libc:__mbtowc_sb(0xff33f728, 0xffbff134, 0xffbff41c, 0x1)
<- libc:mbtowc() = 1
-> libc:wctomb(0x234ec, 0x30, 0xffbff41c, 0x1)
-> libc:__wctomb_sb(0xff33f728, 0x234ec, 0x30, 0x1)
<- libc:wctomb() = 1
-> libc:mbtowc(0xffbff134, 0xffbff41d, 0x1, 0x1)
-> libc:__mbtowc_sb(0xff33f728, 0xffbff134, 0xffbff41d, 0x1)
<- libc:mbtowc() = 1
-> libc:wctomb(0x234ed, 0x30, 0xffbff41d, 0x1)
-> libc:__wctomb_sb(0xff33f728, 0x234ed, 0x30, 0x1)
<- libc:wctomb() = 1
-> libc:mbtowc(0xffbff134, 0xffbff41e, 0x1, 0x1)
-> libc:__mbtowc_sb(0xff33f728, 0xffbff134, 0xffbff41e, 0x1)
<- libc:mbtowc() = 1
-> libc:wctomb(0x234ee, 0x30, 0xffbff41e, 0x1)
-> libc:__wctomb_sb(0xff33f728, 0x234ee, 0x30, 0x1)
<- libc:wctomb() = 1
-> libc:mbtowc(0xffbff134, 0xffbff41f, 0x1, 0x1)
-> libc:__mbtowc_sb(0xff33f728, 0xffbff134, 0xffbff41f, 0x1)
<- libc:mbtowc() = 1
-> libc:wctomb(0x234ef, 0x78, 0xffbff41f, 0x1)
-> libc:__wctomb_sb(0xff33f728, 0x234ef, 0x78, 0x1)
<- libc:wctomb() = 1
-> libc:mbtowc(0xffbff134, 0x234e8, 0x1, 0x1)
-> libc:__mbtowc_sb(0xff33f728, 0xffbff134, 0x234e8, 0x1)
<- libc:mbtowc() = 1
-> libc:strtol(0x234e9, 0xffbff134, 0x0, 0x1)
<- libc:strtol() = 4096
-> libc:strtoul(0xffbff421, 0xffbff134, 0x0, 0x1)
<- libc:strtoul() = 123
-> libc:realloc(0x242e0, 0x1001, 0x0, 0x0)
brk(0x00024CB8)                                 = 0
brk(0x00024CB8)                                 = 0
brk(0x00026CB8)                                 = 0
<- libc:realloc() = 0x242e0
-> libc:vsprintf(0x242e0, 0x234e8, 0xffbff100, 0x242d8)
<- libc:vsprintf() = 10000
-> libc:realloc(0x23ad0, 0x2710, 0x0, 0x0)
    Incurred fault #6, FLTBOUNDS  %pc = 0xFF2C1E7C
      siginfo: SIGSEGV SEGV_MAPERR addr=0x30328320
    Received signal #11, SIGSEGV [default]
      siginfo: SIGSEGV SEGV_MAPERR addr=0x30328320

You can see that vsprintf() is used to write the format directive into a
buffer that has been allocated with size 2049 and reallocated to size 4097.

Here's a proposed doc patch:

*** autoconf.texi.bak   2007-04-24 00:31:05.000000000 +0200
--- autoconf.texi       2007-04-24 00:33:13.000000000 +0200
***************
*** 12700,12705 ****
--- 12700,12712 ----
  bash: printf: `%': missing format character
  @end example
  
+ A format directive that produces more than 2048 bytes of output crashes
+ the @command{printf} of Solaris 10:
+ 
+ @example
+ printf %010000x 123
+ @end example
+ 
  
  @item @command{read}
  @c ------------------





reply via email to

[Prev in Thread] Current Thread [Next in Thread]