You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by st...@apache.org on 2022/08/08 23:37:13 UTC
[impala] 16/27: IMPALA-11365: Dereferencing null pointer in TopNNode
This is an automated email from the ASF dual-hosted git repository.
stigahuang pushed a commit to branch branch-4.1.1
in repository https://gitbox.apache.org/repos/asf/impala.git
commit 822fcf32744d323f101ebf9b03ac7d869785ba62
Author: Daniel Becker <da...@cloudera.com>
AuthorDate: Thu Jun 16 16:44:08 2022 +0200
IMPALA-11365: Dereferencing null pointer in TopNNode
In the constructor of TopNNode, if 'pnode.partition_comparator_config_'
is NULL, we initialise 'partition_cmp_' with a NULL pointer. However,
when initialising 'partition_heaps_', we dereference 'partition_cmp_'
because 'ComparatorWrapper' expects a reference.
This has so far not lead to a crash because in this case the comparator
of 'partition_heaps_' is not used, but assigning a NULL pointer to a
reference is undefined behaviour.
After this change, instead of assigning a NULL pointer to
'partition_cmp_', we use a dummy comparator, and no undefined behaviour
is invoked.
Change-Id: I0b15b06f608b4d17fdf8a24e05967aaa16ebb79c
Reviewed-on: http://gerrit.cloudera.org:8080/18629
Reviewed-by: Zoltan Borok-Nagy <bo...@cloudera.com>
Tested-by: Impala Public Jenkins <im...@cloudera.com>
---
be/src/exec/topn-node.cc | 29 ++++++++++++++++++++++++++++-
be/src/util/tuple-row-compare.h | 6 ++++++
2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/be/src/exec/topn-node.cc b/be/src/exec/topn-node.cc
index fc4318637..f65af7df3 100644
--- a/be/src/exec/topn-node.cc
+++ b/be/src/exec/topn-node.cc
@@ -121,6 +121,33 @@ Status TopNPlanNode::CreateExecNode(RuntimeState* state, ExecNode** node) const
return Status::OK();
}
+/// In the TopNNode constructor if 'pnode.partition_comparator_config_' is NULL, we use
+/// this dummy comparator to avoid 'partition_cmp_' becoming a null pointer. This is
+/// needed because 'partition_cmp_' is wrapped in a
+/// 'ComparatorWrapper<TupleRowComparator>' that takes a reference to the underlying
+/// comparator, so we cannot pass in a null pointer or dereference it.
+class DummyTupleRowComparator: public TupleRowComparator {
+ public:
+ DummyTupleRowComparator()
+ : TupleRowComparator(dummy_scalar_exprs_, dummy_codegend_compare_fn_) {
+ }
+ private:
+ static const std::vector<ScalarExpr*> dummy_scalar_exprs_;
+ static const CodegenFnPtr<TupleRowComparatorConfig::CompareFn>
+ dummy_codegend_compare_fn_;
+
+ int CompareInterpreted(const TupleRow* lhs, const TupleRow* rhs) const override {
+ // This function should never be called as this is a dummy comparator.
+ DCHECK(false);
+ return std::less<const TupleRow*>{}(lhs, rhs);
+ }
+};
+
+/// Initialise vector length to 0 so no buffer needs to be allocated.
+const std::vector<ScalarExpr*> DummyTupleRowComparator::dummy_scalar_exprs_{0};
+const CodegenFnPtr<TupleRowComparatorConfig::CompareFn>
+DummyTupleRowComparator::dummy_codegend_compare_fn_{};
+
TopNNode::TopNNode(
ObjectPool* pool, const TopNPlanNode& pnode, const DescriptorTbl& descs)
: ExecNode(pool, pnode, descs),
@@ -129,7 +156,7 @@ TopNNode::TopNNode(
output_tuple_desc_(pnode.output_tuple_desc_),
order_cmp_(new TupleRowLexicalComparator(*pnode.ordering_comparator_config_)),
partition_cmp_(pnode.partition_comparator_config_ == nullptr ?
- nullptr :
+ static_cast<TupleRowComparator*>(new DummyTupleRowComparator()) :
new TupleRowLexicalComparator(*pnode.partition_comparator_config_)),
intra_partition_order_cmp_(pnode.intra_partition_comparator_config_ == nullptr ?
nullptr :
diff --git a/be/src/util/tuple-row-compare.h b/be/src/util/tuple-row-compare.h
index 2a2be7d82..c17253cc3 100644
--- a/be/src/util/tuple-row-compare.h
+++ b/be/src/util/tuple-row-compare.h
@@ -179,6 +179,12 @@ class TupleRowComparator {
static const char* LLVM_CLASS_NAME;
protected:
+ TupleRowComparator(const std::vector<ScalarExpr*>& ordering_exprs,
+ const CodegenFnPtr<TupleRowComparatorConfig::CompareFn>& codegend_compare_fn)
+ : ordering_exprs_(ordering_exprs),
+ codegend_compare_fn_(codegend_compare_fn) {
+ }
+
/// References to ordering expressions owned by the plan node which owns the
/// TupleRowComparatorConfig used to create this instance.
const std::vector<ScalarExpr*>& ordering_exprs_;