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