You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by mi...@apache.org on 2026/09/21 23:30:34 UTC

(impala) branch master updated: IMPALA-15379: Fix UBSan VLA-bound-0 aborts

This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git


The following commit(s) were added to refs/heads/master by this push:
     new e55545f2d IMPALA-15379: Fix UBSan VLA-bound-0 aborts
e55545f2d is described below

commit e55545f2d1ad901e30fb663ba566de4e173ba98e
Author: Michael Smith <mi...@cloudera.com>
AuthorDate: Thu Sep 17 10:12:07 2026 -0700

    IMPALA-15379: Fix UBSan VLA-bound-0 aborts
    
    ExecNode::CodegenEvalConjuncts declared a C-style VLA
    (llvm::Function* conjunct_fns[conjuncts.size()]) to hold codegen'd
    conjunct functions. When a scan node has zero conjuncts (e.g. a
    query with no WHERE clause), conjuncts.size() is 0, and a VLA with a
    runtime bound of 0 is undefined behavior. UBSan's vla-bound check
    flags this as fatal in future Clang versions, aborting impalad mid-query
    (reproduced by
    TestNestedCollectionsInSelectList::test_array_in_select_list).
    
    Tuple::CodegenMaterializeExprs and
    TupleRowComparatorConfig::CodegenLexicalCompare have similar cases when
    inputs are empty.
    
    Replace VLAs with a std::vector.
    
    Change-Id: I9d476f5adc47d2a9e368a8960fa4e7c3817f43fd
    Assisted-by: Claude Sonnet 5 (GitHub Copilot)
    Reviewed-on: http://gerrit.cloudera.org:8080/24890
    Reviewed-by: Jiyoung Yoo <ji...@cloudera.com>
    Reviewed-by: Joe McDonnell <jo...@cloudera.com>
    Reviewed-by: Michael Smith <mi...@cloudera.com>
    Tested-by: Michael Smith <mi...@cloudera.com>
---
 be/src/exec/exec-node.cc         | 2 +-
 be/src/runtime/tuple.cc          | 2 +-
 be/src/util/tuple-row-compare.cc | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/be/src/exec/exec-node.cc b/be/src/exec/exec-node.cc
index 288c88c1e..a5a1dd56a 100644
--- a/be/src/exec/exec-node.cc
+++ b/be/src/exec/exec-node.cc
@@ -641,7 +641,7 @@ bool ExecNode::WaitForRuntimeFilters(RuntimeState* state,
 //
 Status ExecNode::CodegenEvalConjuncts(LlvmCodeGen* codegen,
     const vector<ScalarExpr*>& conjuncts, llvm::Function** fn, const char* name) {
-  llvm::Function* conjunct_fns[conjuncts.size()];
+  vector<llvm::Function*> conjunct_fns(conjuncts.size());
   for (int i = 0; i < conjuncts.size(); ++i) {
     RETURN_IF_ERROR(conjuncts[i]->GetCodegendComputeFn(codegen, false, &conjunct_fns[i]));
     if (i >= LlvmCodeGen::CODEGEN_INLINE_EXPRS_THRESHOLD) {
diff --git a/be/src/runtime/tuple.cc b/be/src/runtime/tuple.cc
index 0b7761284..31d703dbd 100644
--- a/be/src/runtime/tuple.cc
+++ b/be/src/runtime/tuple.cc
@@ -416,7 +416,7 @@ Status Tuple::CodegenMaterializeExprs(LlvmCodeGen* codegen, bool collect_varlen_
   llvm::LLVMContext& context = codegen->context();
 
   // Codegen each compute function from slot_materialize_exprs
-  llvm::Function* materialize_expr_fns[slot_materialize_exprs.size()];
+  vector<llvm::Function*> materialize_expr_fns(slot_materialize_exprs.size());
   for (int i = 0; i < slot_materialize_exprs.size(); ++i) {
     Status status = slot_materialize_exprs[i]->GetCodegendComputeFn(
         codegen, false, &materialize_expr_fns[i]);
diff --git a/be/src/util/tuple-row-compare.cc b/be/src/util/tuple-row-compare.cc
index fdb760e15..08ff632b5 100644
--- a/be/src/util/tuple-row-compare.cc
+++ b/be/src/util/tuple-row-compare.cc
@@ -235,7 +235,7 @@ Status TupleRowComparatorConfig::CodegenLexicalCompare(
     LlvmCodeGen* codegen, llvm::Function** fn) {
   llvm::LLVMContext& context = codegen->context();
   const vector<ScalarExpr*>& ordering_exprs = ordering_exprs_;
-  llvm::Function* key_fns[ordering_exprs.size()];
+  vector<llvm::Function*> key_fns(ordering_exprs.size());
   for (int i = 0; i < ordering_exprs.size(); ++i) {
     Status status = ordering_exprs[i]->GetCodegendComputeFn(codegen, false, &key_fns[i]);
     if (!status.ok()) {