Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to completely ignore variadic arguments to a C function?

I'm have a function that roughly looks like so:

typedef struct SomeType {
  ...
} SomeType;

void TakesArgs(SomeType *t1, ...) {
     // iterates through arguments
}

// usage:
TakesArgs(&a, &b, &c);

Do I run any strange risks with memory (or otherwise) if I were to change TakesArgs to a no-op, while still leaving all calling code unchanged?

void TakesArgs(SomeType *t1, ...) {
    return;
}

// usage unchanged: 
TakesArgs(&a, &b, &c);

In other words, will skipping the va_list/va_start dance that was executed in the original implementation have any strange side effects?

like image 337
Matt H. Avatar asked Jul 07 '15 22:07

Matt H.


People also ask

What is the purpose of variadic functions?

Variadic functions are functions that can take a variable number of arguments. In C programming, a variadic function adds flexibility to the program. It takes one fixed argument and then any number of arguments can be passed.

How can attackers exploit variadic functions?

An adversary can take advantage of a mismatch between the argument types used by the caller of a variadic function and the types expected by the callee to violate the language semantics and to tamper with memory. Format string attacks are the most popular example of such a mismatch.

Can you pass Va_list to another function?

The va_list may be passed as an argument to another function, but calling va_arg() within that function causes the va_list to have an indeterminate value in the calling function. As a result, attempting to read variable arguments without reinitializing the va_list can have unexpected behavior.

What means variadic?

variadic (not comparable) (computing, mathematics, linguistics) Taking a variable number of arguments; especially, taking arbitrarily many arguments.


2 Answers

Yes, it is perfectly safe. You are not required to read all variadic arguments just for the sake of reading them. You are not required to even start the variadic argument reading sequence inside TakesArgs.

Under the hood it usually means that the burden of performing any argument-passing maintenance tasks is bestowed upon the calling code (they way it works in what is usually recognized as "traditional" C calling convention). The callee does not have to do anything.

like image 127
AnT Avatar answered Sep 28 '22 21:09

AnT


[Edited in response to comments.]

There are systems where by default it is the callee's job to pop arguments. That would obviously get you into trouble. But, it's precisely for this reason that variadic functions have to be properly declared, and the declaration has to be properly visible to callers. The reason is that on those systems, variadic functions have to use a non-default calling sequence where the caller pops the arguments, because only the caller can be sure how many there are. So you should be safe as long as your functions are properly declared.

like image 27
Steve Summit Avatar answered Sep 28 '22 20:09

Steve Summit