The AssignExpr constructor may free the "init" pointer via
AssignExpr::TypeCheck(), resulting in a crash due to use-after-free.
To fix the crash bug, this patch copies the `Location` to the stack
instead of using a potentially-dangling pointer.
Make sure unused scopes are freed to fix memory leaks.
The comment inside pop_scope() is now obsolete and I deleted it,
because this commit implements the real solution.
Note that this requires us to add a reference to the
push_existing_scope() call in dbg_eval_expr(), because it never owned
the reference.
Those functions don't have a well-defined reference passing API, and
we had lots of memory leaks here. By using IntrusivePtr, reference
ownership is well-defined.
Use class IntrusivePtr<>.
This reference is necessary because add_type() may discard the
reference and hold only a reference to a clone of our EnumType.
The following source code:
function foo(foo: int) {}
function foo() {}
... first produces this error:
error in crash.zeek, line 1 and crash.zeek, line 2: incompatible types (function(foo:int;) : void and function() : void)
... and then crashes:
Thread 1 "zeek" received signal SIGSEGV, Segmentation fault.
0x000055555617d970 in RecordType::FieldDecl (this=0x555557cbdd80, field=0) at ../src/Type.cc:735
735 return (*types)[field];
(gdb) bt
#0 0x000055555617d970 in RecordType::FieldDecl (this=0x555557cbdd80, field=0) at ../src/Type.cc:735
#1 0x000055555619c0e2 in transfer_arg_defaults (args=0x555557cbf270, recv=0x555557cbdd80) at ../src/Var.cc:315
#2 0x000055555619c40c in begin_func (id=0x555557cbf070, module_name=0x5555579dd4a0 "GLOBAL", flavor=FUNC_FLAVOR_FUNCTION, is_redef=0, t=0x555557cbde00,
attrs=0x0) at ../src/Var.cc:371
#3 0x0000555555f5723b in yyparse () at parse.y:1174
#4 0x0000555556038bf6 in main (argc=5, argv=0x7fffffffe658) at ../src/main.cc:646
This is because `begin_func()` checks if the old and new functions
have the same type via same_type(), but continues anyway, and then
transfer_arg_defaults() crashes because both `Args()` have different
lengths.
When changing this code for 3.0.0, the code-flow changed significantly.
One of the changes lead to exception being re-thrown from Call - which
leads to the function cleanup not always being run. While the Unref of
the framepointer was (correctly) moved into the catch block, the global
frame stack was not cleaned up - and contains an invalid pointer after
encountering an interpreter exception.
This small commit pops the stack and removes the framepointer that was
pushed onto it before re-throwing the exception.
I also think that this change (re-throwing the exception) breaks the
Zeek debugger in significant ways (you cannot debug a script that causes
a Runtime error anymore).
The type declaration `addr_set` happens to result in a `SetType` with
`elements`, but no `indices`, and so ShallowClone() does not increment
any reference counter. However, the `SetType` constructor passed
ownership of a non-existing reference to `TableType`, resulting in a
double free bug (and Zeek crash).
At first, I tried to fix this by obeying the code comment in
SetType::ShallowClone() and pass `indices=nullptr`, but that led to a
crash inside IndexType::IsSubNetIndex(). So this patch attempts to
make the symptom go away by pretending the code comment is simply
wrong, and only corrects the reference counters.
- Minor cleanups in siphash24.h (code style, header include)
- Updated COPYING.3rdparty with new license info
* origin/topic/timw/faster-hashing:
Add a faster siphash24 implementation than the reference one
- Various minor code formatting/styling during the merge
* 'leaks' of https://github.com/MaxKellermann/zeek:
parse.y: fix memory leak in FieldAssignExpr call
parse.y: fix use-after-free bug in open-ended index_slice
Type: fix use-after-free bug in init_type()
Expr: fix memory leak in RecordCoerceExpr::Fold()
Expr: fix memory leak in RecordCoerceExpr::InitVal()
zeekygen/IdentifierInfo: fix memory leak in operator=()
Func: fix memory leaks in get_func_priority()
parse.y: fix several memory leaks after lookup_ID()
Func: fix memory leaks in check_built_in_call()
Var: fix memory leaks in add_global() and add_local()
Var: add missing references to `init` in add{,_and_assign}_local()
parse.y: hold reference on init_expr for zeekygen::Manager::Redef()
Expr: fix two memory leaks in AssignExpr::InitVal()
parse.y: fix memory leak after "&derepcated" without string
RuleMatcher: delete PatternSet instances in destructor (memleak)
option.bif: fix crash bug by referencing `Func`, not `Val`
- Average of 10 runs of 2009-M57-day11-18.trace (release build at -O3):
- Master: 6.027s 93650 bytes max RSS
- Commit: 5.950s 93271 bytes max RSS
- Hashing a fixed 32-byte payload 10 million times with a fixed key:
- Master: 1.397411s
- Commit: 0.998211s
- Minor whitespace tweak in merge
* 'ExpandAndInit_IntrusivePtr' of https://github.com/MaxKellermann/zeek:
Val: pass IntrusivePtr<> to TableVal::ExpandAndInit()
* origin/topic/jsiwek/32bit-compat:
Improve formatting of doubles that are close to integers
Improve HTTP version number comparisons
Add a 32-bit task to Cirrus CI config
Replace va_list fmt() overload with vfmt()
Format tables indexed by patterns consistently across 32-bit/64-bit
Format interval values consistently across 32-bit/64-bit platforms
An unmanaged reference is held on `func_id`, but its `val` reference
is now owned by the `FieldAssignExpr` instance. The `ID` instance
still feels responsible for releasing the `val` reference, but since
nobody ever frees the `ID`, the conflict never causes a crash.
Prior to this, `t` gets assigned from `Expr::InitType()` which returns
a referenced `BroType` to the caller (and init_Type() releases the
reference later).
But `reduce_type()` does not return a referenced `BroType`; so if
`reduce_type()` happens to return a different instance, it will be
released and maybe destroyed, resulting in a use-after-free bug.