My goal is to analyze a code illustrating CWE122 that I found in the NIST database : https://samate.nist.gov/SARD/test-cases/234158/versions/2.0.0 I dont succeed in making the tool emit an alarm for the flaw described in the link above, using eva plugin. I tried with different parameters, but it does not work. Can you provide me the good parameters please ?
1 Answers
Probable cause: different machdep
I believe you are using a 64-bit machdep (architectural configuration), which is the default in Frama-C 24. Adding option -machdep x86_32
should suffice to reproduce the alarm.
Detailed explanation
Here's a simplified version of the SARD test case:
#include <stdio.h>
#include <stdlib.h>
void main() {
double * data = NULL;
/* FLAW: Using sizeof the pointer and not the data type in malloc() */
data = (double *)malloc(sizeof(data));
if (data == NULL) {exit(-1);}
*data = 1.7E300;
{
double * dataCopy = data;
double * data = dataCopy;
/* POTENTIAL FLAW: Attempt to use data, which may not have enough memory allocated */
printf("%lf", *data);
free(data);
}
}
When on a 32-bit architecture (with options -machdep x86_32
or -machdep gcc_x86_32
), sizeof(data)
equals 4, which is less than the size of a double
(8 bytes). In this case (which is the setting used in Frama-C's reproduction of SATE), as soon as we try to assign *data = 1.7E300
, there is a buffer overflow and Frama-C/Eva emits a red alarm.
However, on a 64-bit architecture, sizeof(data)
is 8, which is by coincidence also the size of a double
. Therefore, there is no buffer overflow and no undefined behavior in the code.
Note that the flaw is a "human-level" flaw, that is, it requires knowing that the intention of the programmer was to match its sizeof with the type used in the cast ((double *)
). But other than using some syntactic heuristics for such cases, there is no way to detect it directly on a 64-bit architecture, because there's no actual buffer overflow nor undefined behavior.
It's possible to imagine a portability analysis which tries all possible combinations of sizes and architectures, and reports issues if any of the combinations produces a warning, but I'm not aware of any tools which do it. Instead, what some analyzers do (and so could Frama-C) is to perform one analysis per architectural configuration (e.g. 32-bit, ILP64, LP64, LLP64, etc.) and perform the union/join of alarms for each test case. This would require a fair amount of scripting and double (or more) the overall execution time, but it is technically feasible, and already done by some users concerned with portability.
Historical note: when Frama-C participated in SATE 5, by default it used a 32-bit architecture configuration, and this has been carried over to SATE 6 by adding -machdep x86_32
General remarks on reproducing tests from SATE
The options used for the SATE 6 reproduction are located in the fc_analyze.sh script, more specifically the flags assigned to FCFLAGS
and EVAFLAGS
(the former concern parsing and general flags; the latter are specific to the Eva plugin):
FCFLAGS="\
-no-autoload-plugins -load-module from,inout,report,eva,variadic \
-kernel-warn-key parser:decimal-float=inactive \
-kernel-warn-key typing:no-proto=inactive \
-kernel-warn-key typing:implicit-conv-void-ptr=inactive \
-eva-warn-key locals-escaping=inactive \
-add-symbolic-path $TESTCASESUPPORT_DIR:TESTCASESUPPORT_DIR \
-machdep x86_32 \
"
EVAFLAGS="\
-eva-msg-key=-initial-state,-final-states \
-eva-no-show-progress \
-eva-print-callstacks \
-eva-slevel 300 \
-warn-special-float none \
-warn-signed-downcast \
-warn-unsigned-overflow \
-eva-warn-copy-indeterminate=-@all \
-eva-no-remove-redundant-alarms \
-eva-domains equality,sign \
-eva-verbose 0 \
"
(Options -no-autoload-plugins
and -load-module
are mostly for performance issues when running 40k+ tests, and can be removed; and -add-symbolic-path
is for versioning test oracles, but can equally be removed.)
Obtaining the command-line used by Frama-C
If you are able to re-run the SATE6 test scripts, that is, if you can go to the directory:
C/testcases/CWE122_Heap_Based_Buffer_Overflow/s11
And run:
make CWE122_Heap_Based_Buffer_Overflow__sizeof_double_31_bad.res
Or:
make CWE122_Heap_Based_Buffer_Overflow__sizeof_double_31_bad.gui
Then a quick hack to obtain the direct command-line used by Frama-C for that test is to modify the fc/analyze.sh
script and add a -x
flag to the first line:
- #!/bin/bash -eu
+ #!/bin/bash -eux
That way, whenever you run a test case, you will get a (fairly large) command line which should hopefully help reproduce the test case.
But, overall, copying the options from FCFLAGS
and EVAFLAGS
should be sufficient to reproduce the analyses.

- 8,264
- 3
- 34
- 78