Bug 217064 - setvbuf() causes glibc to try to munmap() a piece of the brk() area
Summary: setvbuf() causes glibc to try to munmap() a piece of the brk() area
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: glibc
Version: 6
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Jakub Jelinek
QA Contact: Brian Brock
URL:
Whiteboard:
Depends On:
Blocks: 217041
TreeView+ depends on / blocked
 
Reported: 2006-11-23 15:58 UTC by Arjan van de Ven
Modified: 2007-11-30 22:11 UTC (History)
1 user (show)

Fixed In Version: 2.5.90-13
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2006-12-15 13:10:17 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Arjan van de Ven 2006-11-23 15:58:54 UTC
testcase:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <wchar.h>
#include <error.h>

int main(int argc, char **argv)
{
        char name[] = "/tmp/wprintf.out.XXXXXX";
        int fd;
        FILE *fp;
        fd = mkstemp (name);
        fp = fdopen (dup (fd), "a");
        if (fp == NULL)
                error (EXIT_FAILURE, errno, "fdopen(,\"a\")");
        setvbuf (fp, NULL, _IONBF, 0);
        fwprintf (fp, L"hello.\n");   
        fclose (fp);
        return EXIT_SUCCESS;
}

strace of the testcase:
getpid()                                = 10951
open("/tmp/wprintf.out.dr4WZ4", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
dup(3)                                  = 4
fcntl(4, F_GETFL)                       = 0x8002 (flags O_RDWR|O_LARGEFILE)
fcntl(4, F_SETFL, O_RDWR|O_APPEND|O_LARGEFILE) = 0
brk(0)                                  = 0x601000
brk(0x622000)                           = 0x622000
fstat(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0x2b15e8210000
lseek(4, 0, SEEK_CUR)                   = 0
munmap(0x2b15e8210000, 4096)            = 0
lseek(4, 0, SEEK_CUR)                   = 0
write(4, "h", 1)                        = 1
write(4, "e", 1)                        = 1
write(4, "l", 1)                        = 1
write(4, "l", 1)                        = 1
write(4, "o", 1)                        = 1
write(4, ".", 1)                        = 1
write(4, "\n", 1)                       = 1
close(4)                                = 0
munmap(0x601093, 4096)                  = -1 EINVAL (Invalid argument)

note the -EINVAL

part of /proc/self/maps:

00400000-00401000 r-xp 00000000 fd:00 3414911      /tmp/a.out
00600000-00601000 rw-p 00000000 fd:00 3414911      /tmp/a.out
00601000-00622000 rw-p 00601000 00:00 0            [heap]
38e2200000-38e221a000 r-xp 00000000 fd:00 7372823  /lib64/ld-2.5.so
38e2419000-38e241a000 r--p 00019000 fd:00 7372823  /lib64/ld-2.5.so


and see how 0x601093 is in the heap. The testcase is lucky that it's not
page-aligned and the kernel decides to -EINVAL it... otherwise glibc would have
done... interesting things to the heap.

Comment 1 Jakub Jelinek 2006-11-24 10:03:00 UTC
Well, it will never be page aligned, unless you have 1 byte pages.
Anyway, worth fixing...

Comment 2 Jakub Jelinek 2006-12-15 13:10:17 UTC
Should be fixed in glibc-2.5.90-13.


Note You need to log in before you can comment on or make changes to this bug.