GCC Poison

Microsoft has taken a more proactive security stance in its developer toolchain since the inception of its SDLC in the mid-2000′s. One of the earlier steps their SDLC used to reduce vulnerable code was to introduce a header file named banned.h. What this header file does is use an MSVC pragma to deprecate functions that developers typically use incorrectly, and consequently implement remote code execution vulnerabilities in their applications. These functions are the usual suspects: strcpy, sprintf, memcpy, CopyMemory, RtlCopyMemory, strcat, alloca and many more Win32 specific stuff. Way back in its initial release banned.h had similar support for GCC, but it was removed sometime in 2008. I don’t recall exactly why or when but it doesn’t make much sense for Microsoft to maintain that functionality anyway.

Even today in 2013 much of the legacy software that is still critical to many enterprises contains code that calls these vulnerable library functions. Despite modern memory protections like ASLR and DEP the vulnerabilities these functions introduce are still exploitable under the right conditions.

Unfortunately there still doesn’t seem to be an equivalent to banned.h available for projects using GCC so I started a project page for one at GitHub. It uses the GCC poison pragma which bans a specific identifier from your code. As far as I know GCC does not recommend using pragma’s (but to be fair I don’t recommend using GCC when Clang is an option). There are some caveats to this approach though, if the identifier was part of an expanded macro before the identifier was poisoned then it will not throw an error. This is by design because you don’t want GCC throwing errors for unsafe calls made in header files beyond your control. Heres an example of how the pragma works:

#include <stdio.h>
#include <string.h>

#pragma GCC poison strcpy

int main(int argc, char *argv[]) {
  char buf[10];
  strcpy(buf, argv[1]);
  return 0;
}

$ gcc -o string string.c
string.c: In function ‘main’:
string.c:8:2: error: attempt to use poisoned “strcpy”

It’s simple but it can be very helpful when you’ve got a lot of legacy C code sitting around that you want to remove these functions from and keep developers from committing and compiling new code that contains them. For the initial release of gcc-poison we have created a small list of unsafe C functions in the form of a header file you include your source just like you do with banned.h. I must emphasize ‘small’ here for a couple of important reasons.

Microsoft can ban many more simple functions because their libc has secure equivalents, but GNU libc lacks them so our list isn’t as comprehensive. A good example of this is the memcpy function. It is arguably the source of a large number of buffer overflows but it simply isn’t practical to remove it from most programs. Fixing these issues requires functionality that the poison pragma does not provide such as compiler extensions and secure equivalents. The new C11 standard defines some of these secure replacement functions in the ‘Bounds Checking Interfaces’ section but as far as I can tell the glibc maintainers have opted not to implement them and they are outside the scope of GCC development.

The goal of using our poison.h (or something like it) is to help secure legacy code. It is far from complete but you should be able to use it in internal projects by adding all those custom API’s you deprecated in 2004 but can’t seem to stop developers from using.

6 thoughts on “GCC Poison

  1. Chris Rohlf

    @antarmukam @michaelm1234 you can definitely find safer alternatives out there but they may not be well tested. I also think the real value from this approach is in banning in-house APIs and not just standard libc stuff.

    Reply
  2. Pingback: codescaling | Multiprocess Firefox, Kexec and Secure Boot, Poisoning GCC and OpenNebula 4.4 – Snippets

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s