tkomatsu/webserv

CGIでオーバーフローが発生

Closed this issue · 0 comments

下記コマンドでテストを実施しました。

make debug
make httptest

結果は以下のとおりです。
CGIの処理内でヒープ領域のオーバーフローが発生しているようです。

11. default.conf: redirect 301

GET /kapouet/ HTTP/1.1
User-Agent: python-requests/2.25.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive

status_code is 301
header has the key, Content-Length
header has the key, Location
=================================================================
==14012==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60d000000750 at pc 0x00010845934f bp 0x7ffee78858d0 sp 0x7ffee78858c8
WRITE of size 8 at 0x60d000000750 thread T0
    #0 0x10845934e in CGI::SetEnvs() CGI.cpp:128
    #1 0x10845600d in CGI::CGI(Request const&, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, config::Config const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) CGI.cpp:15
    #2 0x108459e42 in CGI::CGI(Request const&, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, config::Config const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) CGI.cpp:13
    #3 0x10837f9cf in Client::GenProcessForCGI(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Client.cpp:231
    #4 0x108378f41 in Client::Preprocess() Client.cpp:204
    #5 0x108378143 in Client::RecvRequest(int) Client.cpp:43
    #6 0x1083ba369 in WebServ::ReadClient(std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::__value_type<int, ISocket*>, std::__1::__tree_node<std::__1::__value_type<int, ISocket*>, void*>*, long> >) WebServ.cpp:130
    #7 0x1083b928d in WebServ::ExecClientEvent(std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::__value_type<int, ISocket*>, std::__1::__tree_node<std::__1::__value_type<int, ISocket*>, void*>*, long> >) WebServ.cpp:183
    #8 0x1083b680c in WebServ::Activate() WebServ.cpp:36
    #9 0x10846fce0 in main main.cpp:15
    #10 0x7fff6b10dcc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)

0x60d000000750 is located 0 bytes to the right of 144-byte region [0x60d0000006c0,0x60d000000750)
allocated by thread T0 here:
    #0 0x10860517d in wrap_malloc+0x9d (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x4917d)
    #1 0x1084572b5 in CGI::SetEnvs() CGI.cpp:88
    #2 0x10845600d in CGI::CGI(Request const&, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, config::Config const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) CGI.cpp:15
    #3 0x108459e42 in CGI::CGI(Request const&, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, config::Config const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) CGI.cpp:13
    #4 0x10837f9cf in Client::GenProcessForCGI(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Client.cpp:231
    #5 0x108378f41 in Client::Preprocess() Client.cpp:204
    #6 0x108378143 in Client::RecvRequest(int) Client.cpp:43
    #7 0x1083ba369 in WebServ::ReadClient(std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::__value_type<int, ISocket*>, std::__1::__tree_node<std::__1::__value_type<int, ISocket*>, void*>*, long> >) WebServ.cpp:130
    #8 0x1083b928d in WebServ::ExecClientEvent(std::__1::__map_iterator<std::__1::__tree_iterator<std::__1::__value_type<int, ISocket*>, std::__1::__tree_node<std::__1::__value_type<int, ISocket*>, void*>*, long> >) WebServ.cpp:183
    #9 0x1083b680c in WebServ::Activate() WebServ.cpp:36
    #10 0x10846fce0 in main main.cpp:15
    #11 0x7fff6b10dcc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)

SUMMARY: AddressSanitizer: heap-buffer-overflow CGI.cpp:128 in CGI::SetEnvs()
Shadow bytes around the buggy address:
  0x1c1a00000090: fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa
  0x1c1a000000a0: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fd
  0x1c1a000000b0: fd fd fd fd fd fd fa fa fa fa fa fa fa fa fd fd
  0x1c1a000000c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x1c1a000000d0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
=>0x1c1a000000e0: 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa
  0x1c1a000000f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c1a00000100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c1a00000110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c1a00000120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c1a00000130: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==14012==ABORTING