Showing posts with label C/C++. Show all posts
Showing posts with label C/C++. Show all posts

Wednesday, March 5, 2008

Recursion unsafe in C/C++?

One of the guys who is writing CouchDB, wrote up this this interesting note: Recursion unsafe in C/C++. It starts off with this

The question of "why disallow recursion in C++?" came up in a comment to the C++ coding standards for the Joint Strike Fighter.

I was just thinking the same thing. ha!

Sunday, January 6, 2008

stringencoders 3.7.0 released

Hi all,

I just released stringencoders 3.7.0. This fixes autotool/libtool which was borked on some platforms according to my spies. It also fixes up some C++ header annoyances. There are no logic changes, so if there is no need to update if it has been working for you so far.

BUT, if you haven't updated since 3.4, please do so since 3.4 has a core dumping bug, and 3.5 are some minor issues with modp_dtoa.

enjoy

Sunday, November 25, 2007

SSI Secure Software Test for C

As mentioned in the last post, the Secure Software Institute is granting Secure Software Programmers certification. i took the C sample test online. While I can't cut-n-paste from the sample test, the questions for the C/C++ are similar to this:

What line contains a security issue:

1   #include 
2   int main(int argc, char** argv) {
3       printf("%d\n", argc);
4       printf(argv[1]);
5       return 0;
6  }

The answer is line 4, since the "format string" is coming from the user. If the string contains "%d" and "%s" formats in it, C will start filling in values off the stack which can lead to nastiest. You want to change line 4 to printf("%s\n", argv[1]);, or in this bad example if (argc > 1) { printf("%s\n", argv[1]); } Ok, so now you know. The other questions are more obscure.

So are you suppose to go through all your code and make these nit-picky changes? Like that's going to work. Like you're going to have time to even do that. Even if you did "fix your existing" code, new code, patches, changes are constantly coming in. And humans aren't so good with details -- they'll make mistakes. Certification in secure programming is just a start in security.

For this example, the issue can be caught automatically with gcc, by adding -Wformat-security or -Wformat=2. It's not caught with -Wall -Wextra -pedantic

$gcc -v
... gcc version 4.0.1 ...

$ gcc -Wformat=2 -Wall -Wextra -Werror -pedantic foo.c
cc1: warnings being treated as errors
foo.c: In function ‘main’:
foo.c:4: warning: format not a string literal and no format arguments

Ok, that does it. I'm writing a new book on C/C++ and software engineering. Really. Stay tuned for details.

Wednesday, November 21, 2007

The Joys of Rounding

Quick! What is the output of this:

#include 
int main() {
    printf("%.1f %1.f %.1f", 1.5, 2.5, 3.5);
    return 0;
}

It turns out Unix based systems (at least on linux glibc and bsd/mac systems), use Round-To-Even rules (this is good):

2 2 3

But on Windows, it's Round-Half-Up (this is bad)

2 3 4

For truly portable programs, you'll need to use a 3rd party implementation of printf (see APR, NSPR or GLIB)

Unfortunately I can't test this for C++ and it's formatting styles and see if there is a difference between Unix and Microsoft systems.

Sunday, November 18, 2007

Whoops, I forgot the optimization flag

So it turns out if you use macports on Mac OS 10.5, python2.5 is compiled without any optimization. This makes it run at least 2x slower than the version in /usr/bin (the bug report is here).

I only noticed this since I'm a nerd and tuned on verbose/debug flags on macports and then thought it was weird that I didn't see the usual -O2. I then wrote a minor benchmark to confirm that indeed, the macports version is slower.

Which reminds me of major screwups I have done involving pushing debug code live instead of the normal optimized version (in that case it was C++ code). In this case I think it took 6 hours of many people's time to "undo" since all the servers were on fire and end customers were pissed off.

Besides turning on al compiler warnings, besides running your unit tests, besides running your integration tests, you also need to have some type of minor performance test to catch these problems. Even the simplest test will catch these type of problems. And it's not just for C++: even if you are writing using a scripting language, the packager of the language can screw up, or use a different optimization between builds, or use a different compile or just not use the best optimization possible.

In the macport example, it appears that some tweeks needed to be done to make python compile on the new OS. In the process of fixing that, the optimizer flags were ignored silently. Nothing was "removed". I've done the same thing fiddling with Makefiles. I didn't remove optimization, I just screwed up some rules, so the wrong flags were used. In other words, it's really easy to this.

Have a performance smoke test