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

Bug#380195: libc6: snprintf(buf, sizeof(buf), "%.2000000000s", "hello") may fail



Package: libc6
Version: 2.3.6-16
Severity: normal

Hello,

The following program prints "-1" rather than "5" on my laptop:

    #include <stdio.h>
    #include <limits.h>

    int main()
    {
	char buf[256];
	printf("%d\n", snprintf(buf, sizeof(buf), "%.2000000000s", "hello"));
	return 0;
    }

Here is the strace:

    execve("/tmp/a.out", ["/tmp/a.out"], [/* 95 vars */]) = 0
    uname({sys="Linux", node="ligate", ...}) = 0
    brk(0)                                  = 0x804a000
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f5c000
    access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f5b000
    open("/etc/ld.so.cache", O_RDONLY)      = 3
    fstat64(3, {st_mode=S_IFREG|0644, st_size=78547, ...}) = 0
    mmap2(NULL, 78547, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f47000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3
    read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240O\1"..., 512) = 512
    fstat64(3, {st_mode=S_IFREG|0755, st_size=1241392, ...}) = 0
    mmap2(NULL, 1247388, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e16000
    mmap2(0xb7f3d000, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x127) = 0xb7f3d000
    mmap2(0xb7f44000, 10396, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f44000
    close(3)                                = 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e15000
    mprotect(0xb7f3d000, 20480, PROT_READ)  = 0
    set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e156c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
    munmap(0xb7f47000, 78547)               = 0
    mmap2(NULL, 2000003072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
    brk(0)                                  = 0x804a000
    brk(0x7f3c4000)                         = 0x804a000
    mmap2(NULL, 2000134144, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
    mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0xb7c15000
    munmap(0xb7c15000, 962560)              = 0
    munmap(0xb7e00000, 86016)               = 0
    mprotect(0xb7d00000, 135168, PROT_READ|PROT_WRITE) = 0
    mmap2(NULL, 2000003072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
    fstat64(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
    ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfa70118) = -1 ENOTTY (Inappropriate ioctl for device)
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f5a000
    write(1, "-1\n", 3)                     = 3
    munmap(0xb7f5a000, 4096)                = 0
    exit_group(0)                           = ?
    Process 6984 detached

The same program correctly prints "5" on my desktop, and here is the
strace:

    execve("./a.out", ["./a.out"], [/* 91 vars */]) = 0
    uname({sys="Linux", node="reincarnation", ...}) = 0
    brk(0)                                  = 0x804a000
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f80000
    access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
    open("/etc/ld.so.cache", O_RDONLY)      = 3
    fstat64(3, {st_mode=S_IFREG|0644, st_size=84156, ...}) = 0
    mmap2(NULL, 84156, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f6b000
    close(3)                                = 0
    access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
    open("/lib/tls/i686/cmov/libc.so.6", O_RDONLY) = 3
    read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240O\1"..., 512) = 512
    fstat64(3, {st_mode=S_IFREG|0755, st_size=1241392, ...}) = 0
    mmap2(NULL, 1247388, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7e3a000
    mmap2(0xb7f61000, 28672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x127) = 0xb7f61000
    mmap2(0xb7f68000, 10396, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f68000
    close(3)                                = 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7e39000
    mprotect(0xb7f61000, 20480, PROT_READ)  = 0
    set_thread_area({entry_number:-1 -> 6, base_addr:0xb7e398e0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
    munmap(0xb7f6b000, 84156)               = 0
    mmap2(NULL, 2000003072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40adf000
    munmap(0x40adf000, 2000003072)          = 0
    fstat64(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
    ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbf892e80) = -1 ENOTTY (Inappropriate ioctl for device)
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f7f000
    write(1, "5\n", 2)                      = 2
    munmap(0xb7f7f000, 4096)                = 0
    exit_group(0)                           = ?
    Process 5022 detached

The difference seems to be whether the call to mmap2 after the
call to set_thread_area succeeds.  It seems that glibc is trying
to allocate almost 2G of memory in order to print into a 256-byte
buffer, and there is not enough address space for the allocation.
(My laptop kernel (custom 2.6.16) config sets CONFIG_NOHIGHMEM=y and
CONFIG_VMSPLIT_3G=y, whereas my desktop kernel (another custom 2.6.16)
sets CONFIG_HIGHMEM4G=y and CONFIG_VMSPLIT_3G=y.)

Thanks,
	Ken

-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.16
Locale: LANG=zh_TW.UTF-8, LC_CTYPE=zh_TW.UTF-8 (charmap=UTF-8)

Versions of packages libc6 depends on:
ii  tzdata                        2006g-2    Time Zone and Daylight Saving Time

libc6 recommends no packages.

-- no debconf information

-- 
Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig
I find it funny how the more interesting something is to me
the harder it is for me to think of a use for it. -- A post on Ars Technica

Attachment: signature.asc
Description: Digital signature


Reply to: