SSP guard value

Robert Connolly cendres at videotron.ca
Fri Mar 19 10:39:08 PST 2004


On the side some of us have been talking about the SSP gaurd value. This list 
is maybe a better place, so I'll try to put together everything so far.
In this: 
http://www.linuxfromscratch.org/patches/downloads/glibc/glibc-2.3.3-ssp-functions-1.patch
You can find this:
void __guard_setup (void)
{
  int fd;
  if (__guard[0]!=0) return;
  fd = open ("/dev/urandom", 0);
  if (fd != -1) {
    ssize_t size = read (fd, (char*)&__guard, sizeof(__guard));
    close (fd) ;
    if (size == sizeof(__guard)) return;
  }
  /* If a random generator can't be used, the protector switches the guard
     to the "terminator canary" */
  ((char*)__guard)[0] = 0; ((char*)__guard)[1] = 0;
  ((char*)__guard)[2] = '\n'; ((char*)__guard)[3] = 255;
}

This is using /dev/urandom to generate a guard value. It works nice but there 
are downsides. It takes 3 syscalls to open, read, and close /dev/urandom 
every time a program runs. This value doesn't need the quality of randomness 
that comes from urandom, and depletes it from the rest of the system.

This uses auxiliary random (ARND) from sysctl. This works on bsd. It, or 
something like it, should work on Linux with some hacking.

static void
__guard_setup(void)
{
        int i, mib[2];
        size_t len;

        if (__guard[0] != 0)
                return;

        mib[0] = CTL_KERN;
        mib[1] = KERN_ARND;

        len = 4;
        for (i = 0; i < sizeof(__guard) / 4; i++) {
                if (__sysctl(mib, 2, (char *)&((int *)__guard)[i],
                    &len, NULL, 0) == -1)
                        break;
        }

        if (i < sizeof(__guard) / 4) {
                /* If sysctl was unsuccessful, use the "terminator canary". */
                ((char *)__guard)[0] = 0; ((char*)__guard)[1] = 0;
                ((char *)__guard)[2] = '\n'; ((char *)__guard)[3] = 255;
        }
}

A bonus to this is that syslog functions might be treated the same way. This 
would drop the dependency for /dev/log too.

The problem is of course, how to do this. Here there is a very old port of 
ARND to Linux:
http://www.redhat.com/archives/linux-security/1997-April/msg00023.html

The other option would be doing it from scratch.

Comments?



More information about the hlfs-dev mailing list