buaazp / zimg

A lightweight and high performance image storage and processing system.
http://zimg.buaa.us
BSD 3-Clause "New" or "Revised" License
2.69k stars 402 forks source link

zimg直接接收chunked数据传输会崩溃 #169

Open sudokuhk opened 7 years ago

sudokuhk commented 7 years ago

在zhttpd.c:781行左右,获取Content-Length的长度,分配buffer,读取POST的数据。 但实际上,chunked数据传输时,Content-Length并不是有效的。 如果存在导致缓冲区溢出崩溃。

`

while((evblen = evbuffer_get_length(buf)) > 0)  //获取的是Content-Length的长度

{
    LOG_PRINT(LOG_DEBUG, "evblen = %d", evblen);
    rmblen = evbuffer_remove(buf, buff, evblen);  //实际chunked的数据
    LOG_PRINT(LOG_DEBUG, "rmblen = %d", rmblen);
    if(rmblen < 0)
    {
        LOG_PRINT(LOG_DEBUG, "evbuffer_remove failed!");
        LOG_PRINT(LOG_ERROR, "%s fail post parse", address);
        err_no = 4;
        goto err;
    }
}

`

buaazp commented 7 years ago

你能复现这个bug吗? 我记得evbuffer_get_length就是req body的长度,而不是header里的值,理论上不会有问题。

sudokuhk commented 7 years ago

可以复现。 修改的代码:

post_size = atoi(content_len);
    LOG_PRINT(LOG_DEBUG, "Content-Length:%d", post_size);
 while((evblen = evbuffer_get_length(buf)) > 0)
    {
        LOG_PRINT(LOG_DEBUG, "evblen = %d", evblen);
        rmblen = evbuffer_remove(buf, buff, evblen);
        LOG_PRINT(LOG_DEBUG, "rmblen = %d", rmblen);
        if(rmblen < 0)
        {
            LOG_PRINT(LOG_DEBUG, "evbuffer_remove failed!");
            LOG_PRINT(LOG_ERROR, "%s fail post parse", address);
            err_no = 4;
            goto err;
        }
    }

捕获的日志:

2017/01/16 16:45:43:963975 Thread ID: 140346756511488 [DEBUG] /home/sudoku/git/zimg/src/zhttpd.c:709 post_request_cb() Method: 2
2017/01/16 16:45:43:964061 Thread ID: 140346756511488 [DEBUG] /home/sudoku/git/zimg/src/zhttpd.c:747 post_request_cb() Content-Length:4096
2017/01/16 16:45:43:964099 Thread ID: 140346756511488 [DEBUG] /home/sudoku/git/zimg/src/zhttpd.c:790 post_request_cb() evblen = 337610

我的测试代码位于: https://github.com/sudokuhk/net-utility

  1. 执行make && cp /.so utest/
  2. 进入utest目录,执行make test_uimg
  3. 执行命令 ./test_uimg -h 127.0.0.1 -p 4869 -c -m upload -f test_uimg