Uploaded image for project: 'Couchbase Server'
  1. Couchbase Server
  2. MB-21776

FailoverTable serialisation/deserialization can change seqno

    XMLWordPrintable

Details

    • Bug
    • Resolution: Won't Fix
    • Minor
    • 5.0.0
    • 3.1.6, 4.1.2, 4.6.0
    • couchbase-bucket
    • Untriaged
    • Unknown

    Description

      During testing with UBSan (http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) I have identified an issue with how the FailoverTable is serialised to/from JSON.

      The fundamental issue is that we use JSON Number to store the 64bit seqnos, and our JSON library (cJSON) represents all Numbers as the C double type.

      As such, when we serialise the UUID and seqno they can become rounded - at flagged by UBSan (the actual warning was about saving into the int half of a cJSON object):

      /home/daver/repos/couchbase/server/platform/src/cJSON.c:901:22: runtime error: value 2.62498e+14 is outside the range of representable values of type 'int'
          #0 0x7f06416422ee in cJSON_CreateNumber /home/daver/repos/couchbase/server/platform/src/cJSON.c:901:22
          #1 0x7c19f9 in FailoverTable::cacheTableJSON() /home/daver/repos/couchbase/server/ep-engine/src/failover-table.cc:221:42
      

      The code in question:

      void FailoverTable::cacheTableJSON() {                                                                                                       
          cJSON* list = cJSON_CreateArray();
          table_t::iterator it;
          for(it = table.begin(); it != table.end(); it++) {
              cJSON* obj = cJSON_CreateObject();
              cJSON_AddNumberToObject(obj, "id", (*it).vb_uuid);
      

      If the seqno is greater than the maximum integer value which can be consecutively represented (experiments suggest 144,115,188,075,855,873 on x86-64) then we will essentially not store the high seqno correctly. However, this is a pretty huge number - 144 quadrillion - performing 1M mutations per second per vBucket would take 4,566 years to reach this value, so in reality there isn't an issue.

      Note the UUID is also stored in the same way, however only the lower 48bits are used, which can safely be represented.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            drigby Dave Rigby (Inactive)
            drigby Dave Rigby (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes

                PagerDuty