Could we harden GCC's stack smashing? (Re: Adam Zabrocki's Adventure with stack smashing protection)
Hello, Adam Zabrocki's Adventure with stack smashing protection at (http://blog.pi3.com.pl/?p=485 ) is kind of interesting. It lists some possible weaknesses in GCC's -fstack-protector. Given that the weaknesses happen when the stack has already been smashed I do not think they are critical but they do bug me. I think that the issues happen due to the fundamental problem with the approach that GCC's reporting method is taking. Instead of dealing with the messed up state of the process it could exec a whole new process or simply abort. We could also actually raise our own SIGSEGV signal. I coded up a small illustration of how the exec strategy would work. Thank you, Steven Stewart-Gallus #include #include #include #include /* * In a real implementation this would be a real crash reporting * program. It would use /proc to examine debugging information such * as the command line. It could also do ptrace debugger stuff. It * could also be set by a command line option. */ #define CRASH_REPORTER "/bin/echo" void stack_overflow(void); int main() { stack_overflow(); } void stack_overflow(void) { /* * As soon as possible give control over to a fresh crash reporter * instance. If any bad things happen abort immmediately and don't * risk compromise due to an attack from an enemy. */ /* * Fork a copy of the program to be debugged from the crash * reporter instance. The copy of the program must be the child * because certain systems are hardened to only allow parents of * the processes to do certain debugging tasks. */ pid_t child = fork(); if (-1 == child) { abort(); } if (0 == child) { raise(SIGSTOP); abort(); } /* Don't bother with sprintf to minimize the chance of attacks. */ char child_string[sizeof child + 1]; memcpy(child_string, &child, sizeof child); child_string[sizeof child] = '\0'; /* * execve the crash reporter to use the thinnest possible wrapper * over the system call. */ char * argv[] = { (char *) CRASH_REPORTER, child_string, NULL }; char * envp[] = { NULL }; execve(CRASH_REPORTER, argv, envp); abort(); }
Re: Could we harden GCC's stack smashing? (Re: Adam Zabrocki's Adventure with stack smashing protection)
Thank you, I must then apologize to the GCC mailing list for bringing up something off topic. About GCC's _stack_chk_fail. Yeah, it's much simpler. Personally, I wouldn't trust syslog but I'm not sure of a good alternative. I'll go bother the GLibc people. Thank you, Steven Stewart-Gallus P.S. I'm not sure if the write to the terminal should handle EINTR. I know for pipes that EINTR doesn't happen on Linux but I have no idea for the /dev/tty special file. - Original Message - From: Ian Lance Taylor Date: Saturday, March 29, 2014 1:03 pm Subject: Re: Could we harden GCC's stack smashing? (Re: Adam Zabrocki's Adventure with stack smashing protection) To: Steven Stewart-Gallus Cc: GCC Development > On Sat, Mar 29, 2014 at 10:52 AM, Steven Stewart-Gallus > wrote: > > > > Adam Zabrocki's Adventure with stack smashing protection at > > (http://blog.pi3.com.pl/?p=485 ) is kind of interesting. It lists > some possible > > weaknesses in GCC's -fstack-protector. Given that the weaknesses > happen when the > > stack has already been smashed I do not think they are critical > but they do bug > > me. I think that the issues happen due to the fundamental problem > with the > > approach that GCC's reporting method is taking. Instead of > dealing with the > > messed up state of the process it could exec a whole new process > or simply > > abort. We could also actually raise our own SIGSEGV signal. I > coded up a small > > illustration of how the exec strategy would work. > > Thanks. The code in question is actually part of glibc, not GCC. All > GCC does is call __stack_chk_fail. You may want to take your concerns > to the glibc developers--see http://sourceware.org/glibc. > > GCC does have it's own copy of __stack_chk_fail in libssp, but it's > simpler than the glibc version. > > Ian >