Opened 11 years ago
Closed 8 years ago
#686 closed defect (wontfix)
With some condition,ngx_palloc() function will alloc a illegal memory address
| Reported by: | Deming Sun | Owned by: | |
|---|---|---|---|
| Priority: | minor | Milestone: | |
| Component: | nginx-core | Version: | 1.7.x |
| Keywords: | illegal memory address, | Cc: | |
| uname -a: | |||
| nginx -V: | nginx version: nginx/1.7.8 | ||
Description
in ngx_palloc.c the function ngx_palloc:
void * ngx_palloc(ngx_pool_t *pool, size_t size)
{
u_char *m;
ngx_pool_t *p;
if (size <= pool->max) {
p = pool->current;
do {
m = ngx_align_ptr(p->d.last, 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);
}
return ngx_palloc_large(pool, size);
}
at this line
m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT); } at sometimes the value of (p->d.end - p->d.last) may less than align coefficient,then ngx_align_ptr make m larger than p->d.end,after this the "if" compare the value of (p->d.end - m) and size with a type cast, when m > p->d.end , (p->d.end - m) will get a negative numbera(e.g: -1、-2、-3) . Underflow happend here and then p->d.last write a address out of p->d.end. I'm debuging a segmant fault in these days,at last I found p->d.last==0x83e96c p->d.end==0x83e96f after ngx_align_ptr m ==0x83e970 then (size_t) (p->d.end - m)==18446744073709551615 greate larger than size,the p->d.last got a illegl address. after this ngx_palloc will always alloc illegl address. there must add a check of p->d.end and m
Attachments (1)
Change History (10)
by , 11 years ago
| Attachment: | ngx_palloc.c added |
|---|
comment:1 by , 11 years ago
| Status: | new → accepted |
|---|
follow-up: 3 comment:2 by , 11 years ago
comment:3 by , 11 years ago
Replying to Ruslan Ermilov:
The problem can only be seen if pool size is not a multiple of
sizeof(long). This is not possible with the stock nginx code - all pool sizes are at least 16-bytes aligned (theNGX_POOL_ALIGNMENTmacro).
Are you developing your own module or using some 3rd-party modules for nginx?
I'm using ngx_lua and pcre.(I do a little modify on ngx_lua,It's using my own pool.).It's happend when ngx_lua call pcre_compile function.pcre use a callback to malloc memory from ngx_pool of the my own pool.
I think if the pool size or alloc size isn't aligned should only decrease performance not cause memory problem.
comment:4 by , 11 years ago
I'm confirmd.When the problem happend the poolsize is not aligned with 16-bytes definitely.But i think it's better to don't alloc illegl address when the poolsize or alloc size not aligned.
For example , In the conf file if "connection_pool_size" or "request_pool_size" configured to a number not aligned with 16-bytes may be cause memory corruption.
follow-up: 6 comment:5 by , 11 years ago
You can't set connection_pool_size or request_pool_size to an unaligned value, nginx will complain during configuration parsing, see ngx_http_core_pool_size() function.
comment:6 by , 11 years ago
Replying to Maxim Dounin:
You can't set connection_pool_size or request_pool_size to an unaligned value, nginx will complain during configuration parsing, see ngx_http_core_pool_size() function.
ok,I know.
comment:7 by , 11 years ago
Alought nginx stock code has no chance to tigger this problem, but I think it's a "trap" for 3rd-party modules developer.Generally considered the size is not aligned only affect memory performance without causing memory corruption.
comment:9 by , 8 years ago
| Resolution: | → wontfix |
|---|---|
| Status: | accepted → closed |
The requirements of ngx_create_pool() are currently documented (see f29bd40e9a62):
ngx_create_pool(size, log)— Create a pool with specified block size. The pool object returned is allocated in the pool as well. The size should be at leastNGX_MIN_POOL_SIZEand a multiple ofNGX_POOL_ALIGNMENT.
This is believed to be enough, no further changes are planned.

The problem can only be seen if pool size is not a multiple of
sizeof(long). This is not possible with the stock nginx code - all pool sizes are at least 16-bytes aligned (theNGX_POOL_ALIGNMENTmacro).Are you developing your own module or using some 3rd-party modules for nginx?