From c8151c31cc7561a13be18e2aa29c06f66a9951e2 Mon Sep 17 00:00:00 2001 From: Karoliine Holter Date: Wed, 28 Jan 2026 14:09:10 +0200 Subject: [PATCH 1/2] Add test for overflows due to mult in calloc implementation --- .../39-signed-overflows/17-calloc-mult-speculating.c | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/regression/39-signed-overflows/17-calloc-mult-speculating.c diff --git a/tests/regression/39-signed-overflows/17-calloc-mult-speculating.c b/tests/regression/39-signed-overflows/17-calloc-mult-speculating.c new file mode 100644 index 0000000000..243c516a8d --- /dev/null +++ b/tests/regression/39-signed-overflows/17-calloc-mult-speculating.c @@ -0,0 +1,8 @@ +// PARAM: --enable ana.int.interval +#include + +int main() { + size_t a, b; + unsigned char *randomString = (unsigned char *)calloc(a,b); // NOWARN (signed integer overflow in *) + return 0; +} From 4be6a4fbde7e285d7dbc8b482ff8dbcf00773b5d Mon Sep 17 00:00:00 2001 From: Karoliine Holter Date: Wed, 28 Jan 2026 14:11:31 +0200 Subject: [PATCH 2/2] Fix spurious * overflow check in calloc implementation --- src/analyses/base.ml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/analyses/base.ml b/src/analyses/base.ml index 9aa421dc54..e1e3276104 100644 --- a/src/analyses/base.ml +++ b/src/analyses/base.ml @@ -2763,7 +2763,10 @@ struct let blob_set = Option.map_default (fun heap_var -> [heap_var, TVoid [], VD.Blob (VD.bot (), sizeval, ZeroInit.calloc)]) [] heap_var in set_many ~man st ((eval_lv ~man st lv, (Cilfacade.typeOfLval lv), Address addr):: blob_set) else - let blobsize = ID.mul (ID.cast_to ~kind:Internal ik @@ sizeval) (ID.cast_to ~kind:Internal ik @@ countval) in (* TODO: proper castkind *) + let blobsize = (* only speculative during ID.mul *) + let@ () = GobRef.wrap AnalysisState.executing_speculative_computations true in + ID.mul (ID.cast_to ~kind:Internal ik @@ sizeval) (ID.cast_to ~kind:Internal ik @@ countval) (* TODO: proper castkind *) + in let offset = `Index (IdxDom.of_int (Cilfacade.ptrdiff_ikind ()) Z.zero, `NoOffset) in (* the heap_var is the base address of the allocated memory, but we need to keep track of the offset for the blob *) let addr_offset = AD.map (fun a -> Addr.add_offset a offset) addr in