Uploaded image for project: 'C Driver'
  1. C Driver
  2. CDRIVER-1351

libbson aborts or segfaults on invalid base64 $binary data

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 1.4.0
    • Affects Version/s: None
    • Component/s: libbson
    • Labels:
    • Fully Compatible

      When given invalid "$binary" data libbson will crash with either an explicit abort or a segmentation fault.

      An abort is caused when the first binary type parsed is invalid.

       static void
       test_bson_json_read_corrupt_binary(void)
       {
          bson_error_t error;
          const char *json = "{ "
              " \"a\" : { \"$numberLong\" : \"1\" },"
              " \"invalid\" : { \"$binary\" : \"invalid\", \"$type\" : \"80\" } }";
          bson_t b;
          bool r;
          char *str;
      
          // This will abort "src/bson/bson.c:789 bson_append_binary(): precondition failed: binary"
          r = bson_init_from_json (&b, json, -1, &error);
          assert (!r);
      
          bson_destroy (&b);
       }
      

      Abort stack trace:

      ➜  libbson git:(master) ✗ .libs/test-libbson -l /bson/json/read/corrupt_binary --no-fork
      {
        "host": {
          "sysname": "Darwin",
          "release": "15.5.0",
          "machine": "x86_64",
          "memory": {
            "pagesize": 4096,
            "npages": 4194304
          }
        },
        "options": {
          "parallel": false,
          "fork": false
        },
        "results": [
      src/bson/bson.c:789 bson_append_binary(): precondition failed: binary
      [1]    58981 abort (core dumped)  .libs/test-libbson -l /bson/json/read/corrupt_binary --no-fork
      ➜  libbson git:(master) ✗ lldb -c /cores/core.58981 .libs/test-libbson
      (lldb) target create ".libs/test-libbson" --core "/cores/core.58981"
      warning: (x86_64) /cores/core.58981 load command 64 LC_SEGMENT_64 has a fileoff + filesize (0x269b3000) that extends beyond the end of the file (0x269b2000), the segment will be truncated to match
      warning: (x86_64) /cores/core.58981 load command 65 LC_SEGMENT_64 has a fileoff (0x269b3000) that extends beyond the end of the file (0x269b2000), ignoring this section
      Core file '/cores/core.58981' (x86_64) was loaded.
      (lldb) bt
      * thread #1: tid = 0x0000, 0x00007fff8e1b3f06 libsystem_kernel.dylib`__pthread_kill + 10, stop reason = signal SIGSTOP
        * frame #0: 0x00007fff8e1b3f06 libsystem_kernel.dylib`__pthread_kill + 10
          frame #1: 0x00007fff8bf0c4ec libsystem_pthread.dylib`pthread_kill + 90
          frame #2: 0x00007fff8e3a56e7 libsystem_c.dylib`abort + 129
          frame #3: 0x0000000105107814 libbson-1.0.0.dylib`bson_append_binary + 468
          frame #4: 0x000000010511243c libbson-1.0.0.dylib`_bson_json_read_end_map + 1244
          frame #5: 0x000000010511b0b6 libbson-1.0.0.dylib`yajl_do_parse + 1574
          frame #6: 0x0000000105110358 libbson-1.0.0.dylib`bson_json_reader_read + 360
          frame #7: 0x0000000105110993 libbson-1.0.0.dylib`bson_init_from_json + 227
          frame #8: 0x00000001050d32d1 test-libbson`test_bson_json_read_corrupt_binary + 65
          frame #9: 0x00000001050c1a4a test-libbson`TestSuite_RunTest + 426
          frame #10: 0x00000001050c1375 test-libbson`TestSuite_Run + 341
          frame #11: 0x00000001050c1f68 test-libbson`main + 200
          frame #12: 0x00007fff889725ad libdyld.dylib`start + 1
      

      A segfault is caused when a valid binary object is parsed before the invalid one.

       static void
       test_bson_json_read_corrupt_binary2(void)
       {
          bson_error_t error;
          const char *json = "{ "
              " \"valid\" : { \"$binary\" : \"YXNkZmFz\", \"$type\" : \"80\" },"
              " \"invalid\" : { \"$binary\" : \"invalid\", \"$type\" : \"80\" } }";
          bson_t b;
          bool r;
          char *str;
      
          // This causes a segmentation fault
          r = bson_init_from_json (&b, json, -1, &error);
          assert (!r);
      
          bson_destroy (&b);
       }
      

      segfault stack trace:

      ➜  libbson git:(master) ✗ .libs/test-libbson -l /bson/json/read/corrupt_binary2 --no-fork
      {
        "host": {
          "sysname": "Darwin",
          "release": "15.5.0",
          "machine": "x86_64",
          "memory": {
            "pagesize": 4096,
            "npages": 4194304
          }
        },
        "options": {
          "parallel": false,
          "fork": false
        },
        "results": [
      [1]    59011 segmentation fault (core dumped)  .libs/test-libbson -l /bson/json/read/corrupt_binary2 --no-fork
      ➜  libbson git:(master) ✗ lldb -c /cores/core.59011 .libs/test-libbson
      (lldb) target create ".libs/test-libbson" --core "/cores/core.59011"
      warning: (x86_64) /cores/core.59011 load command 63 LC_SEGMENT_64 has a fileoff + filesize (0x268b3000) that extends beyond the end of the file (0x268b2000), the segment will be truncated to match
      warning: (x86_64) /cores/core.59011 load command 64 LC_SEGMENT_64 has a fileoff (0x268b3000) that extends beyond the end of the file (0x268b2000), ignoring this section
      Core file '/cores/core.59011' (x86_64) was loaded.
      (lldb) bt
      * thread #1: tid = 0x0000, 0x00007fff9627df49 libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 41, stop reason = signal SIGSTOP
        * frame #0: 0x00007fff9627df49 libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 41
          frame #1: 0x000000010c7914dd libbson-1.0.0.dylib`_bson_append + 429
          frame #2: 0x000000010c791774 libbson-1.0.0.dylib`bson_append_binary + 308
          frame #3: 0x000000010c79c43c libbson-1.0.0.dylib`_bson_json_read_end_map + 1244
          frame #4: 0x000000010c7a50b6 libbson-1.0.0.dylib`yajl_do_parse + 1574
          frame #5: 0x000000010c79a358 libbson-1.0.0.dylib`bson_json_reader_read + 360
          frame #6: 0x000000010c79a993 libbson-1.0.0.dylib`bson_init_from_json + 227
          frame #7: 0x000000010c759361 test-libbson`test_bson_json_read_corrupt_binary2 + 65
      

            Assignee:
            shane.harvey@mongodb.com Shane Harvey
            Reporter:
            shane.harvey@mongodb.com Shane Harvey
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: