telefonicaid / fiware-orion

Context Broker and CEF building block for context data management, providing NGSI interfaces.
https://github.com/telefonicaid/fiware-orion/blob/master/doc/manuals/orion-api.md
GNU Affero General Public License v3.0
210 stars 265 forks source link

Possible illegal read access on zero page in APIv1 in StatusCode.cpp #3609

Open 0xricksanchez opened 4 years ago

0xricksanchez commented 4 years ago

Check my reasoning in #3603

Sending malformed JSON entities to the context.Orion_LD (compiled with an Address Sanitizer) V1 API can ultimately result in a illegal READ access on a zero page in /opt/fiware-orion/src/lib/ngsi/StatusCode.cpp:

From the marked line over here

/opt/fiware-orion/src/lib/serviceRoutines/postUpdateContext.cpp:447
* ****************************************************************************
*
* foundAndNotFoundAttributeSeparation -
*
* Examine the response from mongo to find out what has really happened ...
*
*/
static void foundAndNotFoundAttributeSeparation(UpdateContextResponse* upcrsP, UpdateContextRequest* upcrP, ConnectionInfo* ciP)
{
  ContextElementResponseVector  notFoundV;
[...]
  //
  // If nothing at all in response vector, mark as not found (but not if DELETE request)
  //
  if (ciP->method != "DELETE")
  {
    if (upcrsP->contextElementResponseVector.size() == 0)
    {
      if (upcrsP->errorCode.code == SccOk)
      {
        upcrsP->errorCode.fill(SccContextElementNotFound, upcrP->entityVector[0]->id);  <-----------------
      }
    }
  }

The crash occurs finally occurs here:

/opt/fiware-orion/src/lib/ngsi/StatusCode.cpp:149
/* ****************************************************************************
*
* StatusCode::fill -
*/
void StatusCode::fill(HttpStatusCode _code, const std::string& _details)
{
  code          = _code;
  reasonPhrase  = httpStatusCodeString(code);
  details       = _details;     <----------------
}

Crash

orion_1  | ASAN:DEADLYSIGNAL
orion_1  | =================================================================
orion_1  | ==1==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 0x7fed74efcb4e bp 0x0ffdacd65d60 sp 0x7fed66b2ea40 T1207)
orion_1  | ==1==The signal is caused by a READ memory access.
orion_1  | ==1==Hint: address points to the zero page.
orion_1  |     #0 0x7fed74efcb4d in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x124b4d)
orion_1  |     #1 0x564f2d482955 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/include/c++/7/bits/basic_string.h:1356
orion_1  |     #2 0x564f2d482955 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/include/c++/7/bits/basic_string.h:685
orion_1  |     #3 0x564f2d482955 in StatusCode::fill(HttpStatusCode, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /opt/fiware-orion/src/lib/ngsi/StatusCode.cpp:149
orion_1  |     #4 0x564f2cff38e5 in foundAndNotFoundAttributeSeparation /opt/fiware-orion/src/lib/serviceRoutines/postUpdateContext.cpp:447
orion_1  |     #5 0x564f2cff38e5 in postUpdateContext(ConnectionInfo*, int, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, ParseData*, Ngsiv2Flavour) /opt/fiware-orion/src/lib/serviceRoutines/postUpdateContext.cpp:577
orion_1  |     #6 0x564f2d1e2a14 in restService /opt/fiware-orion/src/lib/rest/RestService.cpp:708
orion_1  |     #7 0x564f2d1e7a9f in orion::requestServe[abi:cxx11](ConnectionInfo*) /opt/fiware-orion/src/lib/rest/RestService.cpp:787
orion_1  |     #8 0x564f2d1c6d88 in connectionTreat /opt/fiware-orion/src/lib/rest/rest.cpp:1580
orion_1  |     #9 0x564f2d8043e7 in call_connection_handler /opt/libmicrohttpd-0.9.48/src/microhttpd/connection.c:1585
orion_1  |     #10 0x564f2d805929 in MHD_connection_handle_idle /opt/libmicrohttpd-0.9.48/src/microhttpd/connection.c:2624
orion_1  |     #11 0x564f2d8082bd in MHD_handle_connection /opt/libmicrohttpd-0.9.48/src/microhttpd/daemon.c:998
orion_1  |     #12 0x7fed75f506da in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76da)
orion_1  |     #13 0x7fed7455288e in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x12188e)
orion_1  | AddressSanitizer can not provide additional info.
orion_1  | SUMMARY: AddressSanitizer: SEGV (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x124b4d) in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
orion_1  | Thread T1207 created by T14 here:
orion_1  |     #0 0x7fed76eb3d2f in __interceptor_pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x37d2f)
orion_1  |     #1 0x564f2d80887f in create_thread /opt/libmicrohttpd-0.9.48/src/microhttpd/daemon.c:1230
orion_1  | Thread T14 created by T0 here:
orion_1  |     #0 0x7fed76eb3d2f in __interceptor_pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x37d2f)
orion_1  |     #1 0x564f2d80887f in create_thread /opt/libmicrohttpd-0.9.48/src/microhttpd/daemon.c:1230
orion_1  | ==1==ABORTING

Recorded responsible test case

{"contextElements": [{󠁩"type": "Room", "isPattern": "false","id": "Room1", "attributes": [{"name": "temperature", "type": "float", "value": "26.5", metadata󠁉"s": [{"name": "accuracy", "type": "float", "value": "0".8}]}]}], "updateAction": ": APPEND"}
fgalan commented 4 years ago

Thanks for the feedback!

Looking to the "Recorded responsible test case" I'm not sure in which sense this JSON is malformed... Could you elaborate so I can try to reproduce, please?

fgalan commented 4 years ago

Looking to the "Recorded responsible test case" I'm not sure in which sense this JSON is malformed... Could you elaborate so I can try to reproduce, please?

In other words, how I can generate the request (e.g. with a curl command) that is causing the crash.

@0xricksanchez what do you think?