Atoi() vulnerability against fault injection - c

I’m using atoi to convert an string to integer in a embedded c application. However, I could exploit the vulnerability in atoi() using clock glitching fault injection attack. I mean when I have a single or multiple glitch, the processor missed some characters and returns faulty integer. Is there any alternative for atoi function which is more robust against fault injection? Can I use its complementary (itoa function) to regenerate the string and compare two strings?
I saw the strtol function as an alternative for validation instead of atoi(). could that be a case for my problem or it just returns the software errors?

This is a typical case of a CPU controlled by a Schrödinger cat. With her quantic paws, she can decide which instructions to execute or skip...
It is difficult to imagine code that would be resilient in such an environment.
As a matter of fact, any attempt at testing output consistency could be defeated by skipping the corresponding instructions.
As commented by Barmar, you could just call atoi() twice and compare the values, hoping for a moment of distraction of the clock glitcher.

Related

Parsing a MAC Address to an array of three 16-bit shorts

MAC Addresses are 48 bits. That is equivalent to three shorts. MAC
addresses are sometimes written like this: 01:23:45:67:89:ab where
each pair of digits represents a hexadecimal number.
Write a function that will take in a character pointer pointing to a
null terminated string of characters like in the example and will
break it apart and then store it in an array of three 16-bit shorts.
The address of the array will also be passed into the function.
I figured the function header should look something like void convertMacToShort(char *macAddr, short *shorts);. What I'm having difficulty with is parsing the char*. I feel like it's possible if I loop over it, but that doesn't feel efficient enough. I don't even need to make this a universal function of sorts--the MAC address will always be a char* in the format of 01:23:45:67:89:ab.
What's a good way to go about parsing this?
Well efficiency is one thing ... robustness another.
If you have very defined circumstances like a list of millions of MAC addresses which are all in the same format (only lower case letters, always leading zeroes, ...) then I would suggest using a quick function accessing the characters directly.
If you're parsing user input and need to detect input errors as well, execution speed is not the thing to worry about. In this scenario you have to make sure that you detect all possible mistakes a user is able to do (and this is quite a feat). This leads to sscanf(..) and in that case I would even suggest to write your own function which parses the string (for my experience sscanf(..) sometimes causes trouble depending on the input string and therefore I avoid using it when processing user input).
Another thing: If you're worrying about efficiency in the means of execution time, write a little benchmark which runs the parsing function a few million times and compare execution time. This is easily done and sometimes brings up surprises...

Input/ Output alternatives for printf/scanf

It may sound strange that knowing a lot about iOS and having some experience in .net, I am a newcomer to C. Somewhere I got this target to find average of n numbers without using printf and scanf. I don't want the code for the program but I am seeking alternatives to the mentioned functions.
Is code with printf/scanf required here? Also do let me know if my query stands invalid.
No, neither printf nor scanf is really needed for this.
The obvious alternatives would be to read the input with something like getc or fgets and convert from characters to numbers with something like strtol.
On the output side, you'd more or less reverse that, converting from numbers to characters (e.g., with itoa which is quite common, though not actually standard), then printing out the resulting string (e.g., with fputs).

How do the execution speeds of snprintf and strncat compare?

I have a program which concatenates some number of strings in a buffer.
I was using strncpy before. After looking into some suggetions on web to use snprintf instead of strncat, I switched to snprintf. However, I have noticed a delay in execution of this part of program(string concatenation) then before. Is this possible, that snprintf can slow down the program exucution speed? If not then I will look for some other factors in my program.
if(iOffset<MAX_BUFF_SIZE && iOffset>0)
{
.......
iOffset += snprintf(cBuff+iOffset, sizeof(cBuff)-iOffset, "%s", "String1");
......
}
I repeat the above code snippet like 12 times in order to append strings to cBuff.
Edit : It repeats 12 times after each 1 sec.
There are a couple of suggestions that come to mind:
don't optimize your program too early
when you're ready to optimize, use a tool like a profiler to discover where the real slow downs are
If you're not familiar with profiling, or are really eager to know the timing details you can always include timers around your code. See references on gettimeofday() or clock() and the appropriate caveats about those codes. Essentially you can get the time before execution, the time after and compare them. Comment out your line of code and put in the old code and time it.
With all that said ... that's part of what a profiler does for you. Figuring out "why" something is slow is sometimes complex because there may be other considerations going on (ie at the hardware level) that you're not aware of.
The execution of a function 12 times is probably trivial compared to the total execution time of the program.
strncat suffers from the Schlemiel the Painter problem. The way you're using snprintf does not (though it's possible to use strncat that way too, and sidestep the problem that way).
Copying the "repeated concatenation" idiom and just using snprintf to do it is not genuinely following the suggestion to avoid strcat. You should be doing something like:
snprintf(buf, sizeof buf, "%s%s%s%s", str1, str2, str3, str4);
This will be a lot faster than repeated calls to snprintf, which would incur a lot of overhead for each call, and it would actually be using the idiom correctly.
Assuming that you take into account the issue that Chris Jester-Young referred to, by accounting for the "Schlemiel the Painter" problem, you are likely to find that in a head to head comparison that strncat() is quicker than snprintf() - in the way that you are using it.
snprintf() does have the (albeit minor, in this case) overhead of having to parse the format string that strncat() does not.
The snippet of code that you provided is different enough from the example given in the linked question to potentially change the comparison.
As Stephen has mentioned, for most platforms running strncpy() 12 times versus snprintf() should produce a negligible difference. The use of a profiler would be useful here to make sure that you're concentrating on the right area.
In the example that you have provided you are trying to append a const string to your buffer. If that is what you're doing in your real code (rather than just as a simple example) and the string copying is really a significant area of execution time, you might be able to optimise that area.
One common method of optimisation is to find calculations that can be pre-computed at compile time, rather than at execution time. If you are only interested in handling const strings you may be able to effectively precompute the length of the strings and then use memcpy(), instead of strncpy() to perform the string append. memcpy() is typically very well optimised to your platform.
Of course such a solution would be at the expense of having to take more care of buffer overflows and pointer arithmetic.
I'm not a profiler, so I can't say for sure what is slow.
As #chris mentions, strncat can do more work than it needs to in finding the end of the destination string over and over. You might have been able to mitigate that since it appears you are tracking space consumed, so you can start from the end on each subsequent call.
On the other hand, snprintf likely has to do extra work compared to a strcat or strcpy, because it must parse the "%s" on each call to figure out how to deal with the variable argument list.
I'm not surprised that strncat could run faster, especially in the absence of aggressive optimization levels.
People who mentioned not to optimize early after you noticed a slow down are silly. In this case, you don't even need to run a profiler. You already have empirical evidence switching to snprintf slowed down your program.
I work in the financial industry where performance is key and almost always prefer sprintf to snprintf. It is possible to write fast and stable apps with it within a tigthly controlled environment.

scanf Cppcheck warning

Cppcheck shows the following warning for scanf:
Message: scanf without field width limits can crash with huge input data. To fix this error message add a field width specifier:
%s => %20s
%i => %3i
Sample program that can crash:
#include
int main()
{
int a;
scanf("%i", &a);
return 0;
}
To make it crash:
perl -e 'print "5"x2100000' | ./a.out
I cannot crash this program typing "huge input data". What exactly should I type to get this crash? I also don't understand the meaning of the last line in this warning:
perl -e ...
The last line is an example command to run to demonstrate the crash with the sample program. It essentially causes perl to print 2.100.000 times "5" and then pass this to the stdin of the program "a.out" (which is meant to be the compiled sample program).
First of all, scanf() should be used for testing only, not in real world programs due to several issues it won't handle gracefully (e.g. asking for "%i" but user inputs "12345abc" (the "abc" will stay in stdin and might cause following inputs to be filled without a chance for the user to change them).
Regarding this issue: scanf() will know it should read a integer value, however it won't know how long it can be. The pointer could point to a 16 bit integer, 32 bit integer, or a 64 bit integer or something even bigger (which it isn't aware off). Functions with a variable number of arguments (defined with ...) don't know the exact datatype of elements passed, so it has to rely on the format string (reason for the format tags to not be optional like in C# where you just number them, e.g. "{0} {1} {2}"). And without a given length it has to assume some length which might be platform dependant as well (making the function even more unsave to use).
In general, consider it possibly harmful and a starting point for buffer overflow attacks. If you'd like to secure and optimize your program, start by replacing it with alternatives.
I tried running the perl expression against the C program and it did crash here on Linux (segmentation fault).
Using of 'scanf' (or fscanf and sscanf) function in real-world applications usually is not recommended at all because it's not safe and it's usually a hole for buffer overrun if some incorrect input data will be supplied.
There are much more secure ways to input numbers in many commonly used libraries for C++ (QT, runtime libraries for Microsoft Visual C++ etc.). Probably you can find secure alternatives for "pure" C language too.

Test printf implementation

I would like to have a portable implemenation of my application. However,
I have heard that there are some issues with printf from the stdlib on certain machines
where it does not behave as intended. For instance, when using the conversion specifier
%f then it can happen that on certain architectures the printf implementation
includes a decimal point in the output!
Now I am wondering, if there are maybe some testing routines out there which I could
use to test the semantic correctness of stdlib c implementation, in particular the printf
routine. Maybe there are some good resources that point out some issues when porting programs?
Many thanks,
Heinz
I think Postel's law ("be conservative in what you do, be liberal in what you accept from others") applies here, too. Don't write your tests to require a character-by-character match in order to consider the printf() implementation to be working.
Instead, do it a a higher level; parse the text output by printf() into the expected datatype, and compare against a value of that type.
I.e., if printing "2.25", parse the text (using strtod() or equivalent) and compare against the actual number 2.25, not the literal text string "2.25".
The wine test suite for the msvcrt dll looks interesting : http://github.com/mirrors/wine/blob/master/dlls/msvcrt/tests/printf.c
You should write your own test suite that covers the issues that concern you. It's very simple to call printf 100 times with varying inputs, and the output is simple text, so it's simple to check against the output you expect.
I would recommend to test it in the following way: use sprintf() to produce some testing templates and compare them to your "correct" one.
I did something like this using fprintf (just to avoid the caching in our embedded system).
I think that results would not differ for the printf and sprintf: the formatting algorithm is the same.

Resources