0

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 ?

thomas
  • 11
  • 1

1 Answers1

2
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.

anol
  • 8,264
  • 3
  • 34
  • 78