From df7a47510a94daabec3f55b921212cef3c5917f2 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 5 Mar 2020 17:00:55 +0100 Subject: [PATCH] Expr: reference `id_list` before passing to new `BroFunc` Passing the `id_list` pointer to `BroFunc` transfers ownership of the contained `ID` instances, because `~BroFunc()` unreferences them. Therefore, we need to increase the reference counters for each `BroFunc` instance to fix the use-after-free bug. Closes https://github.com/zeek/zeek/issues/845 --- src/Expr.cc | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index d419298ad8..d4b000723b 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -4283,6 +4283,20 @@ void CallExpr::ExprDescribe(ODesc* d) const args->Describe(d); } +/** + * Create a new #id_list containing new references to the given list. + */ +static std::unique_ptr shallow_copy_id_list(const id_list &src) + { + auto dest = std::make_unique(src.length()); + for (ID *i : src) + { + Ref(i); + dest->push_back(i); + } + return dest; + } + LambdaExpr::LambdaExpr(std::unique_ptr arg_ing, id_list arg_outer_ids) : Expr(EXPR_LAMBDA) { @@ -4297,7 +4311,7 @@ LambdaExpr::LambdaExpr(std::unique_ptr arg_ing, BroFunc* dummy_func = new BroFunc( ingredients->id, ingredients->body, - ingredients->inits, + ingredients->body && ingredients->inits && ingredients->inits->length() > 0 ? shallow_copy_id_list(*ingredients->inits).release() : nullptr, ingredients->frame_size, ingredients->priority); @@ -4345,7 +4359,7 @@ IntrusivePtr LambdaExpr::Eval(Frame* f) const auto lamb = make_intrusive( ingredients->id, ingredients->body, - ingredients->inits, + ingredients->body && ingredients->inits && ingredients->inits->length() > 0 ? shallow_copy_id_list(*ingredients->inits).release() : nullptr, ingredients->frame_size, ingredients->priority);