Skip to content

Commit c1cc31f

Browse files
rdemellowjimwwalker
authored andcommitted
MB-41718: Fix crash due to vbucket nullptr dereference
Currently in DcpProducer::getHighSeqnoOfCollections() there is the possibility that we can end up dereferencing a nullptr as we don't check if getVBucket() returns a valid ptr. To fix this refactor getHighSeqnoOfCollections() to take a ref to a VBucket object as this method is only ever called within DcpProducer::streamRequest() which gains a valid VBucketPtr already. Also move getHighSeqnoOfCollections() to the protected namespace as its only ever used within DcpProducer. Change-Id: I74f86662929503d5d81f04296b4ce30cf1870920 Reviewed-on: http://review.couchbase.org/c/kv_engine/+/138055 Tested-by: Build Bot <[email protected]> Reviewed-by: Jim Walker <[email protected]>
1 parent 6b0d315 commit c1cc31f

File tree

2 files changed

+15
-16
lines changed

2 files changed

+15
-16
lines changed

engines/ep/src/dcp/producer.cc

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -408,16 +408,16 @@ ENGINE_ERROR_CODE DcpProducer::streamRequest(
408408
start_seqno = static_cast<uint64_t>(vb->getHighSeqno());
409409
}
410410

411-
std::pair<bool, std::string> need_rollback = vb->failovers->needsRollback(
412-
start_seqno,
413-
vb->getHighSeqno(),
414-
vbucket_uuid,
415-
snap_start_seqno,
416-
snap_end_seqno,
417-
vb->getPurgeSeqno(),
418-
flags & DCP_ADD_STREAM_STRICT_VBUUID,
419-
getHighSeqnoOfCollections(filter, vbucket),
420-
rollback_seqno);
411+
std::pair<bool, std::string> need_rollback =
412+
vb->failovers->needsRollback(start_seqno,
413+
vb->getHighSeqno(),
414+
vbucket_uuid,
415+
snap_start_seqno,
416+
snap_end_seqno,
417+
vb->getPurgeSeqno(),
418+
flags & DCP_ADD_STREAM_STRICT_VBUUID,
419+
getHighSeqnoOfCollections(filter, *vb),
420+
rollback_seqno);
421421

422422
if (need_rollback.first) {
423423
logger->warn(
@@ -2065,20 +2065,19 @@ bool DcpProducer::isOutOfOrderSnapshotsEnabled() const {
20652065
}
20662066

20672067
std::optional<uint64_t> DcpProducer::getHighSeqnoOfCollections(
2068-
const Collections::VB::Filter& filter, Vbid vbucket) const {
2068+
const Collections::VB::Filter& filter, VBucket& vbucket) const {
20692069
if (filter.isPassThroughFilter()) {
20702070
return std::nullopt;
20712071
}
20722072

20732073
uint64_t maxHighSeqno = 0;
2074-
auto vb = engine_.getVBucket(vbucket);
20752074
for (auto& coll : filter) {
2076-
auto handle = vb->getManifest().lock(coll.first);
2075+
auto handle = vbucket.getManifest().lock(coll.first);
20772076
if (!handle.valid()) {
20782077
logger->warn(
20792078
"({}) DcpProducer::getHighSeqnoOfCollections(): failed "
20802079
"to find collectionID:{}, scopeID:{}, in the manifest",
2081-
vbucket,
2080+
vbucket.getId(),
20822081
coll.first,
20832082
coll.second);
20842083
// return std::nullopt as we don't want our caller to use rollback

engines/ep/src/dcp/producer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ class DcpProducer : public ConnHandler,
371371

372372
bool isOutOfOrderSnapshotsEnabled() const;
373373

374+
protected:
374375
/**
375376
* For filtered DCP, method returns the maximum of all the high-seqnos of
376377
* the collections in the filter. std::nullopt is returned for and
@@ -380,9 +381,8 @@ class DcpProducer : public ConnHandler,
380381
* @return high seqno of all the collection in the filter.
381382
*/
382383
std::optional<uint64_t> getHighSeqnoOfCollections(
383-
const Collections::VB::Filter& filter, Vbid vbucket) const;
384+
const Collections::VB::Filter& filter, VBucket& vbucket) const;
384385

385-
protected:
386386
/** We may disconnect if noop messages are enabled and the last time we
387387
* received any message (including a noop) exceeds the dcpTimeout.
388388
* Returns ENGINE_DISCONNECT if noop messages are enabled and the timeout

0 commit comments

Comments
 (0)