Analyser - variadic arguments

Hello,

I’m trying to write a clang checker to detect when the number of calls to va_arg exceeds the number of variadic arguments passed to a function. An example bug I’d like to be able to detect is shown at the end of this e-mail.

To do this, my plan is to register a map with the program state and, when va_start or va_copy is called, create an entry describing the number of arguments and our position within them. Then calls to va_args can be checked to ensure they’re in that range.

Currently, I’m able to detect calls to va_start and va_args, so I’ll be able to track the position within the argument list - but I’m not sure how to go about getting the length of the list of arguments.

Can anyone advise me on how I should find the number of va_args arguments?

Thanks.

Here’s the progress I’ve made so far - as you can see, it looks a lot like the “Building a Checker in 24 hours” checker: https://github.com/michaeltandy/clang/blob/db5c117d3cdc5287829dd4e55166aeb2ef1ff08a/lib/StaticAnalyzer/Checkers/VariadicChecker.cpp

Example bug code:

#include <stdarg.h>
#include <stdio.h>

static void printArgs(int x, …) {
va_list args;
va_start( args, x );
for (int i=0 ; i<x; i++) {
printf(“%i “, va_arg(args, int));
}
printf(”\n”);
va_end( args );
}

static void printArgs2(int x, …) {
printArgs(x);
}

int main () {
printArgs(4, 1, 2, 3, 4);
printArgs2(4, 1, 2, 3, 4);
return(0);
}

Example bug consequences:

$ ./bin/clang …/stdarg-example2.c
$ ./a.out
1 2 3 4
1 2 0 4

A bit off-fopic:

Kostya, is this something that UBSan could be taught how to detect?

Jon