[C-safe-secure-studygroup] what constitutes a rule violation?

Aaron Ballman aaron at aaronballman.com
Fri Jul 13 16:15:31 BST 2018


On Wed, Jul 11, 2018 at 3:22 PM, Martin Sebor <msebor at gmail.com> wrote:
> I get the impression that we're spending large amounts of time
> with little progress by rehashing the same issue because we're
> not on the same page about a fundamental question: what
> constitutes a rule violation.
>
> Take the following examples.  Assume what you see is the complete
> program that's visible to the analyzer; what's not defined in it
> is in some library that the analyzer doesn't see or have knowledge
> of -- like in the vast majority of software.

CodeSonar allows the user to configure this somewhat (it does not have
fine granularity and is more of a project-wide setting), but by
default it is generally pessimistic and assumes anything can happen
within a function it cannot see. The user can go to the trouble of
writing a model for that function if they'd like, but that's more of
an extreme circumstance and doesn't seem like the scenario you're
asking about (that's more useful for times when you know what the
behavior of the function is but the definition will never be seen by
the tool).

I tried your examples out in three static analysis tools I have handy
right now: clang (through clang-tidy), CodeSonar (with and without
MISRA checks enabled), and Visual Studio's analyzer.

>   extern int f (int*);
>
>   int main (void)
>   {
>     int i;   // uninitialized
>     f (&);
>     return i;
>   }

Clang, Visual Studio, and CodeSonar (in both modes) do not diagnose
the possibly uninitialized variable by default (after fixing the
typo). I was surprised that CodeSonar does not diagnose the return
statement as a violation of MISRA C:2012 Rule 9.1 and found out you
need to enable this manually due to a high false positive rate even
within the MISRA checks.

A related question along these same lines is what should be reported
here, if anything:

int main(void) {
  int *i = (int)malloc(sizeof(int));
  f(i);
  return *i; // Diagnose a use-after-free here? Or is this a null
pointer dereference? Dereferencing an invalid pointer value?
}

> Is it anyone's expectation that the read of i in main violate
> MISRA Rule 9.1 or TS 17961 rule 5.35 (reading uninitialized
> memory), and so requires a diagnostic?
>
> What about if I change main to
>
>   int main (void)
>   {
>     int i;
>     extern int *p = &i;
>     f (0);
>     return i;
>   }
>
> Does this require a diagnostic?  Should it?

Yes and yes. 'p': cannot initialize extern variables with block scope  ;-)

Switching the code to:

extern int f(int*);

int i;
extern int *p = &i;

int main(void)
{
  f(0);
  return i;
}

Clang, Visual Studio, and CodeSonar (in both modes) do not diagnose
the return of i by default, but that seems like reasonable behavior
given that i is zero initialized due to being a file-scope static.

> Or:
>
>   int main (void)
>   {
>     int i;
>     switch (f (0)) {
>     case 0:
>     case 1:
>     case 2: i = 0; break;
>     case -1: i = 1; break;
>     }
>     return i;
>   }
>
> Does this require a diagnostic?

CodeSonar (in both modes), Visual Studio, and Clang all diagnose the
uninitialized variable on "return i".

~Aaron

> What do the analyzers that implement this rule do?  Does
> it change from rule to rule?  Should it be allowed to?
>
> I don't believe we can make forward progress unless we are
> clear on what the answers are or what we want them to be.
> I don't think the spec will have value to users unless it
> makes it clear for each rule what constitutes a violation
> and whether it's considered a certain violation or just
> a possible one.
>
> Martin
>
> _______________________________________________
> C-safe-secure-studygroup mailing list
> C-safe-secure-studygroup at lists.trustable.io
> https://lists.trustable.io/cgi-bin/mailman/listinfo/c-safe-secure-studygroup



More information about the C-safe-secure-studygroup mailing list