You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 7 Next »

Don't bother reading this, yet. I'm still working on it... Dan

A variadic function – a function declared with a parameter list ending with ellipsis (...) – can accept a varying number of arguments of varying types. Variadic functions are flexible, but they are also hazardous. The compiler can't verify that a given call to a variadic function passes an appropriate number of arguments or that those arguments have appropriate types. Consequently, a runtime call to a variadic function that passes inappropriate arguments yields undefined behavior. Such undefined behavior could be exploited to run arbitrary code.

Non-compliant Code Example


Compliant Solution


Exceptions

When a function call appears in some contexts, notably as the argument in a sizeof expression, the compiler performs overload resolution to determine the result type of the call, but the object code doesn't execute the call at runtime. In that case, calling a variadic function does no harm, and can actually be very useful, especially when using template metaprogramming techniques that exploit SFINAE ("substitution failure is not an error").

typedef char True;
typedef struct { char a[2]; } False;

template <typename T>
True isPtr(T *);

False isPtr(...);

#define is_ptr(e) (sizeof(isPtr(e)) == sizeof(True))

In this example, is_ptr(e) returns true if expression e has a pointer type.

Risk Assessment

Incorrectly using a variadic function can result in abnormal program termination, unintended information disclosure, or execution of arbitrary code.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

DCL33-C

3 (high)

2 (probable)

3 (low)

P18

L1

References

[[Dewhurst 03]] Gotcha 55: Runtime Static Initialization

  • No labels