Uploaded image for project: 'Couchbase Lite'
  1. Couchbase Lite
  2. CBL-530

Certain keys in a query can cause segmentation faults

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • Critical
    • 2.8.0
    • 2.7.0
    • LiteCore
    • Security Level: Public
    • None
    • 3

    Description

      https://github.com/couchbase/couchbase-lite-core/issues/864

      The most simple way to trigger bug:

       

      {{$ ./cblite /tmp/sync_docs.cblite2
      Opened read-only database /tmp/sync_docs.cblite2/
      (cblite) query {"WHAT": [".departure_time"], "WHERE": ["AND", ["=",[".type"], "MyDoc"], ["=", ["_.id"], "6ff2ffc3-3b73-44e2-aff2-dfccefd80ad5"]]}
      Segmentation fault (core dumped)}}

      But bug is not related to cblite tool, it is just simple way to trigger it.
      backtrace of cblite:

       

      {{#0 0x000055c8582207ce in fleece::impl::Value::tag() const ()
      (gdb) bt
      #0 0x000055c8582207ce in fleece::impl::Value::tag() const ()
      #1 0x000055c85842ac9a in fleece::impl::Value::type() const ()
      #2 0x000055c85821a687 in litecore::QueryParser::parseNode(fleece::impl::Value const*) ()
      #3 0x000055c85821ccae in litecore::QueryParser::objectPropertyOp(fleece::slice, fleece::impl::Array::iterator&) ()
      #4 0x000055c85821da1c in litecore::QueryParser::fallbackOp(fleece::slice, fleece::impl::Array::iterator&) ()
      #5 0x000055c85821ac27 in litecore::QueryParser::handleOperation(litecore::QueryParser::Operation const*, fleece::slice, fleece::impl::Array::iterator&) ()
      #6 0x000055c85821ab32 in litecore::QueryParser::parseOpNode(fleece::impl::Array const*) ()
      #7 0x000055c85821a7ee in litecore::QueryParser::parseNode(fleece::impl::Value const*) ()
      #8 0x000055c85821a87d in litecore::QueryParser::parseCollatableNode(fleece::impl::Value const*) ()
      #9 0x000055c85821b0e6 in litecore::QueryParser::infixOp(fleece::slice, fleece::impl::Array::iterator&) ()
      #10 0x000055c85821ac27 in litecore::QueryParser::handleOperation(litecore::QueryParser::Operation const*, fleece::slice, fleece::impl::Array::iterator&) ()
      #11 0x000055c85821ab32 in litecore::QueryParser::parseOpNode(fleece::impl::Array const*) ()
      #12 0x000055c85821a7ee in litecore::QueryParser::parseNode(fleece::impl::Value const*) ()
      #13 0x000055c85821a87d in litecore::QueryParser::parseCollatableNode(fleece::impl::Value const*) ()
      #14 0x000055c85821b0e6 in litecore::QueryParser::infixOp(fleece::slice, fleece::impl::Array::iterator&) ()
      #15 0x000055c85821ac27 in litecore::QueryParser::handleOperation(litecore::QueryParser::Operation const*, fleece::slice, fleece::impl::Array::iterator&) ()
      #16 0x000055c85821ab32 in litecore::QueryParser::parseOpNode(fleece::impl::Array const*) ()
      #17 0x000055c85821a7ee in litecore::QueryParser::parseNode(fleece::impl::Value const*) ()
      #18 0x000055c858219453 in litecore::QueryParser::writeWhereClause(fleece::impl::Value const*) ()
      #19 0x000055c858218d35 in litecore::QueryParser::writeSelect(fleece::impl::Value const*, fleece::impl::Dict const*) ()
      #20 0x000055c85821896b in litecore::QueryParser::writeSelect(fleece::impl::Dict const*) ()
      #21 0x000055c858218788 in litecore::QueryParser::parse(fleece::impl::Value const*) ()
      #22 0x000055c8582186ae in litecore::QueryParser::parseJSON(fleece::slice) ()
      #23 0x000055c85826983f in litecore::SQLiteQuery::SQLiteQuery(litecore::SQLiteKeyStore&, fleece::slice, litecore::QueryLanguage) ()
      #24 0x000055c858268d3a in litecore::SQLiteKeyStore::compileQuery(fleece::slice, litecore::QueryLanguage) ()
      #25 0x000055c8581eec23 in c4Query::c4Query(c4Internal::Database*, unsigned int, FLSlice) ()
      #26 0x000055c8581ecba8 in c4query_new2::{lambda()#1}::operator()() const ()
      #27 0x000055c8581ee02d in c4Query* fleece::function_ref<c4Query* ()>::callback_fn<c4query_new2::{lambda()#1}>(long) ()
      #28 0x000055c8581f022c in fleece::function_ref<c4Query* ()>::operator()() const ()
      #29 0x000055c8581efb40 in c4Query* c4Internal::tryCatch<c4Query*>(C4Error*, fleece::function_ref<c4Query* ()>) ()
      #30 0x000055c8581ecccd in c4query_new2 ()}}

      backtrace of my program, which uses couchbase-lite-core directly:

       

      {{#0 0x00007f8929a0d582 in fleece::impl::Value::tag (this=0x0)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/vendor/fleece/Fleece/Core/Value.hh:211
      #1 0x00007f8929c25ad2 in fleece::impl::Value::type (this=0x0)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/vendor/fleece/Fleece/Core/Value.cc:71
      #2 0x00007f8929a10a41 in litecore::QueryParser::parseNode (this=0x7f8926a29ca0, node=0x0)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:547
      #3 0x00007f8929a13098 in litecore::QueryParser::objectPropertyOp (this=0x7f8926a29ca0, op=..., operands=...)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:930
      #4 0x00007f8929a13e06 in litecore::QueryParser::fallbackOp (this=0x7f8926a29ca0, op=..., operands=...)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:1063
      #5 0x00007f8929a10fe1 in litecore::QueryParser::handleOperation (this=0x7f8926a29ca0, op=0x7f8929e35610 <litecore::QueryParser::kOperationList+1872>, actualOperator=..., operands=...)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:627
      #6 0x00007f8929a10eec in litecore::QueryParser::parseOpNode (this=0x7f8926a29ca0, node=0x7f891803b680)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:612
      #7 0x00007f8929a10ba8 in litecore::QueryParser::parseNode (this=0x7f8926a29ca0, node=0x7f891803b680)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:563
      #8 0x00007f8929a10c37 in litecore::QueryParser::parseCollatableNode (this=0x7f8926a29ca0, node=0x7f891803b680)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:576
      #9 0x00007f8929a11486 in litecore::QueryParser::infixOp (this=0x7f8926a29ca0, op=..., operands=...)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:683
      #10 0x00007f8929a10fe1 in litecore::QueryParser::handleOperation (this=0x7f8926a29ca0, op=0x7f8929e35220 <litecore::QueryParser::kOperationList+864>, actualOperator=..., operands=...)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:627
      #11 0x00007f8929a10eec in litecore::QueryParser::parseOpNode (this=0x7f8926a29ca0, node=0x7f891803b6aa)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:612
      #12 0x00007f8929a10ba8 in litecore::QueryParser::parseNode (this=0x7f8926a29ca0, node=0x7f891803b6aa)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:563
      #13 0x00007f8929a10c37 in litecore::QueryParser::parseCollatableNode (this=0x7f8926a29ca0, node=0x7f891803b6aa)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:576
      #14 0x00007f8929a11486 in litecore::QueryParser::infixOp (this=0x7f8926a29ca0, op=..., operands=...)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:683
      #15 0x00007f8929a10fe1 in litecore::QueryParser::handleOperation (this=0x7f8926a29ca0, op=0x7f8929e35460 <litecore::QueryParser::kOperationList+1440>, actualOperator=..., operands=...)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:627
      #16 0x00007f8929a10eec in litecore::QueryParser::parseOpNode (this=0x7f8926a29ca0, node=0x7f891803b6b2)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:612
      #17 0x00007f8929a10ba8 in litecore::QueryParser::parseNode (this=0x7f8926a29ca0, node=0x7f891803b6b2)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:563
      #18 0x00007f8929a0f80d in litecore::QueryParser::writeWhereClause (this=0x7f8926a29ca0, where=0x7f891803b6b2)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:344
      #19 0x00007f8929a0f0ef in litecore::QueryParser::writeSelect (this=0x7f8926a29ca0, where=0x7f891803b6b2, operands=0x7f891803b6ba)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:269
      #20 0x00007f8929a0ed25 in litecore::QueryParser::writeSelect (this=0x7f8926a29ca0, operands=0x7f891803b6ba)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:219
      #21 0x00007f8929a0eb42 in litecore::QueryParser::parse (this=0x7f8926a29ca0, expression=0x7f891803b6ba)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:192
      #22 0x00007f8929a0ea68 in litecore::QueryParser::parseJSON (this=0x7f8926a29ca0, expressionJSON=...)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/QueryParser.cc:183
      #23 0x00007f8929a60d67 in litecore::SQLiteQuery::SQLiteQuery (this=0x7f8918025270, keyStore=..., queryStr=..., language=litecore::QueryLanguage::kJSON)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/SQLiteQuery.cc:81
      #24 0x00007f8929a6390c in litecore::SQLiteKeyStore::compileQuery (this=0x7f8918023f10, selectorExpression=..., language=litecore::QueryLanguage::kJSON)
      at /home/evgeniy/.cargo/git/checkouts/couchbase-lite-rust-a552ad01d6a5c3d0/73911da/couchbase-lite-core-sys/couchbase-lite-core/LiteCore/Query/SQLiteQuery.cc:501
      #25 0x00007f89299e0d7c in c4Query::c4Query (this=0x7f8918040780, db=0x7f8918000d30, language=0, queryExpression=...)}}

      The problem in swap of _ and . in ["_.id"], it would be nice to get error instead of segmentation fault in this case.

      From Jens Alfke -

      According to the backtrace, QueryParser.cc:547 is dereferencing a null Value*.
      The caller of that is objectPropertyOp, whose comment reads Handles object (dict) property accessors, e.g. ["_.", [...], "prop"] --> fl_property(..., "prop").
      That method calls parseNode(operands[0]); before checking that operands is non-empty ... oops. A lot of the xxxOp methods have their operand count checked before they're called, but not this one.

      This could be fixed by adding at the start of the method:
      require(!operands.empty, "Missing receiver for object property");
       

      Attachments

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

        Activity

          People

            jens Jens Alfke
            jimb Jim Borden
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes

                PagerDuty