On Fri, Sep 29, 2023 at 12:11:51PM +0900, Masato Asou wrote:
> I am investigating what problems can bt detected with MALLOC_OPTIONS.
> SEGV occurs even if MALLOC_OPTIONS=G is not specified. Normally, the
> areas allocated by malloc() are not contiguous. However, after many
> malloc() operations and not free() these areas, contiguous areas may
> be allocated. I guessed that MALLOC_OPTIONS=G would be effective in
> this case, is this correct?
>
>
> The above estimates are based on the following research:
>
> I investigated MALLOC_OPTIONS=G using the following program.
>
> $ cat main.c
> #include
> #include
> #include
>
> int
> main(int argc, char *argv[])
> {
> size_t size;
> char*buf;
>
> size = atoi(argv[1]);
> if ((buf = malloc(size)) == NULL)
> err(1, "malloc(%zu) failed", size);
> buf[size] = 1; /* Writes outside the range allocated by malloc */
> free(buf);
>
> return (0);
> }
> $ cc main.c
> $ MALLOC_OPTIONS=G ./a.out 4096
> zsh: segmentation fault (core dumped) MALLOC_OPTIONS=G ./a.out 4096
>
> The program occurred SEGV. Because, malloc() allocates the requested
> size + MALLOC_PAGESIZE area using mmap() as below, and the makes the
> extra MALLOC_PAGESIZE allocated area to be unreadble and unwritable
> using mprotect().
>
> p = mmap(NULL, size + MALLOC_PAGESIZE, ...);
> mprotect(p + size, MALLOC_PAGESIZE, PROT_NONE);
>
> However, SEGV occurs even if not specify MALLOC_OPTIONS=G.
>
> $ ./a.out 4096
> zsh: segmentation fault (core dumped) ./a.out 4096
>
> Because, malloc() allocates the requested size as below:
>
> p = mmap(NULL, size, ...);
>
> Of course, can not read and write to area that exceeded size.
> --
> ASOU Masato
>
In this caseof a single malloc call you'll get a page that is followed
by unmapped memory as the kernel does that. In general, that may not
happen though, depending on what happended previously (i.e. contents
of the caches used by malloc, or just bad luck). G ensures that the
page is followed by a guard page.
-Otto