﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	uname	nginx_version
1454	ngx_palloc may return a heap-buffer-overflow address if the parameter size is not aligned when call ngx_create_pool	Iven Xu		"Hi,
Recently I use nginx as proxy server, and I also write a third-module for nginx. But I found a problem with the nginx pool.
I create a pool with the size 4098(it is a mistake, 4096 is the size that I really want). And I found sometimes the memory address that ngx_palloc returned is wrong.I use AddressSanitizer to detect the memory bugs, the AddressSanitizer will print message like this:
==39791== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6062009a5508 at pc 0x466604 bp 0x7ffd93c864e0 sp 0x7ffd93c864d0
WRITE of size 1 at 0x6062009a5508 thread T0
    #0 0x466603 (nginx+0x466603)
    #1 0x8265de (nginx+0x8265de)
    #2 0x823f67 (nginx+0x823f67)
    #3 0x81c13a (nginx+0x81c13a)
    #4 0x81b3ed (nginx+0x81b3ed)
    #5 0x4700fc (nginx+0x4700fc)
    #6 0x62df01 (nginx+0x62df01)
    #7 0x6017db (nginx+0x6017db)
    #8 0x544f13 (nginx+0x544f13)
    #9 0x55cca5 (nginx+0x55cca5)
    #10 0x55b3b7 (nginx+0x55b3b7)
    #11 0x56b6cf (nginx+0x56b6cf)
    #12 0x53d981 (nginx+0x53d981)
    #13 0x53d4fc (nginx+0x53d4fc)
    #14 0x53d38e (nginx+0x53d38e)
    #15 0x56969f (nginx+0x56969f)
    #16 0x565e87 (nginx+0x565e87)
    #17 0x563d39 (nginx+0x563d39)
    #18 0x55fc95 (nginx+0x55fc95)
    #19 0x502475 (nginx+0x502475)
    #20 0x4d3828 (nginx+0x4d3828)
    #21 0x4fb3a5 (nginx+0x4fb3a5)
    #22 0x4f1f75 (nginx+0x4f1f75)
    #23 0x4f7efe (nginx+0x4f7efe)
    #24 0x4f66a5 (nginx+0x4f66a5)
    #25 0x45b352 (nginx+0x45b352)
    #26 0x7f7e8daa8b14 (/usr/lib64/libc-2.17.so+0x21b14)
    #27 0x45a4d0 (nginx+0x45a4d0)
0x6062009a5508 is located 6 bytes to the right of 4098-byte region [0x6062009a4500,0x6062009a5502)

Finally, I found the reason from the code. It is because of the size of the pool.
Let's look at the ngx_palloc_small. 

static ngx_inline void *
ngx_palloc_small(ngx_pool_t *pool, size_t size, ngx_uint_t align)
{
    u_char      *m;
    ngx_pool_t  *p;

    p = pool->current;

    do {
        m = p->d.last;

        if (align) {
            m = ngx_align_ptr(m, NGX_ALIGNMENT);
        }

        if ((size_t) (p->d.end - m) >= size) {
            p->d.last = m + size;

            return m;
        }

        p = p->d.next;

    } while (p);

    return ngx_palloc_block(pool, size);
}

Suppose the size is 4098 when call ngx_create_pool, so the p->d.end will be not  aligned. If p->d.last = p->d.end - 1(this situation is likely to happen),  p->d.last will be not aligned too. When call ngx_palloc_small with align is set 1, the temporary variables ""m"" is assigned to p->d.last. Because the align is set 1,  ""m"" will be aligned for NGX_ALIGNMENT, and the ""m"" will be larger than p->d.end. The statement of if(  (size_t) (p->d.end - m) >= size )will succeed(p->d.end - m is negative，but it connvert to be size_t which is unsigned). At last, the return memory address is overflow on the heap. For example, p->d.end = 0x6062009a5502, p->d.last = 0x6062009a5501, m = 0x6062009a5508 after alignment. The return memory address is m(0x6062009a5508 ) which is overflow.
This error is caused by the size which is not aligned when I called ngx_create_pool. But it is not a mandatory requirement that the size of pool must be aligned.
So, in my opinion nginx should return a correct memory address even if the size of pool is not aligned. Am I right?"	defect	closed	minor		other	1.13.x	duplicate	pool misaligned		Linux 3.10.106-1-0044 #1 SMP Mon Jul 17 15:20:12 CST 2017 x86_64 x86_64 x86_64 GNU/Linux	nginx version: nginx/1.13.5
