Secure Coding mailing list archives
upwards growing stacks
From: karger at watson.ibm.com (karger at watson.ibm.com)
Date: Fri, 31 Mar 2006 12:55:32 -0500
Steve Bellovin <smb at cs.columbia.edu writes:
I've heard that claim before; I've always thought it overrated. In an upward-growing stack, if you overflow a parameter passed to a subroutine it will overwrite the subroutine's return address. Since many buffer overflows happen as a result of library calls -- think strcpy() or scanf() -- this can be *more* of a danger. The real advantage on Multics was PL/I, where character strings of declared lengths were a built-in data type.
Steve is absolutely correct. The upwards growing stack protects a routine against overflowing its own buffer. If the buffer was passed to the routine by a caller, the upwards growing stack does nothing. However, the PL/I language does provide protection in that case. Assume that the buffer in question is a character string. Similar things were done for arrays and structures. The incoming parameter has to be declared, either with a specified length which is known at compile time, or it must be declared as a char(*) parameter. If it has a specified maximum length (even if is a varying string), the compiler knows what that length is and generates code that either truncates or blank extends assignment statements, as required. If it is a char(*) parameter, then the caller is REQUIRED to pass an argument descriptor that specifies the maximum length. This argument descriptor is created automatically by the compiler of the calling routine. The compiler generates code to use the length in the argument descriptor to do the same truncation or blank extension as required. The software author does not need to write anything about argument descriptors (and indeed, cannot from PL/I). It was all done automatically by the Multics compilers for ALL languages, not just PL/I. What I described above were simple string assignment statements. There is also the substr() function and pseudo-op in PL/I that can specify particular offsets within a string. To get the offset values checked, you had to turn on STRINGRANGE checking which would generate extra code to do the checks. There were probably other checks done by STRINGRANGE that I don't remember. (It's been a LONG time...) I've always thought it a shame that PL/I usage has mostly died out, although IBM still supports it for many machines. The ANSI G subset of PL/I was a quite reasonable language for systems programming, much better than C, and not that much harder to compile than C. Full PL/I is another story. - Paul
Current thread:
- upwards growing stacks karger at watson.ibm.com (Mar 31)