Wednesday March 29, 2006
Avoiding Programming Language Vulnerabilities
This week I am in Berlin at a meeting of the ISO/SC22/WG14, the C programming language committee, in Berlin. One of the hottest topics are dealing with programming security issues and integerity systems.
JTC 1/SC 22 has created a new project to deal with the subject of vulnerabilities in programming languages. The basic technical concept is that all programming languages contain features that are poorly specified, difficult to use correctly, or dependent upon particular implementations. In some cases, these features cause software codes to become vulnerable to malicious parties. The intent of the project is to create guidance on dealing with these problems. In some cases, the guidance will be generic across languages; in other cases the guidance will be specific to languages.
The project is being implemented in an unusual manner. SC22 has created an OWG ("Other Working Group") on Vulnerabilities. This group is convened by, Jim Moore, and the co-convener is John Benito. Jim is the convener of WG9 (Ada) and John is the convener of WG14 (C); so they cover a wide range of programming language design. It is their intent to enlist experts from other working groups so that they can further broaden the range of expertise. They also have permission to enlist experts from non-ISO languages, like Java. Finally, of course, they need participants from national bodies.
The purpose of this blog is to encourage US participation. Because an OWG is not-quite-a-working-group, I believe that the arrangements to participate in it are somewhat informal.
For more information about participating or contacting Jim Moore, have a look at the ISO/IEC JTC 1/SC 22/OWG:Vulnerabilities website http://aitc.aitcnet.org/isai/
I'll be on Vacation next week seeing some of Germany ... :-)
( Mar 29 2006, 07:45:41 AM PST )
Permalink
Comments [1]
Managed strings
I'm off to a meeting of the ISO/SC22/WG14, the C programming language committee meeting in a weeks. Actually, I'm leaving today for a meeting with our my engineering team in St. Petersburg on my way to Berlin for the ISO/SC22/WG14, the C programming language committee meeting. Another piece of work the committee has been working on for over a year now involves Mitigating Security Vulnerabilities. This work is about to turn into a Draft Technical Report, currently titled:
Extensions to the C Library Part I: Bounds-checking interfaces
You can read more about it at:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1146.pdf
there is a rationale at:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1147.pdf
This work has generated alot of interest. One such area is dealing with the vulnerablilities of manipulating strings in C. Robert C. Seacord of Carnegie Mellon University has submitted a paper to the committee with ideas on library routines to manage strings to mitigate these issues. Below is the introduction from the paper, and a link to the full document.
Introduction
String manipulation errors
Many vulnerabilities in C programs arise through the use of the standard C string manipulating functions. String manipulation errors include buffer overflow through string copying, truncation errors, termination errors and improper data sanitization. Buffer overflow can easily occur when copying strings if the fixed-length destination of the copy is not large enough to accommodate the source of the string. This is a particular problem when the source is user input, which is potentially unbounded. The usual programming practice is to allocate a character array that is generally large enough. The problem is that this can easily be exploited by malicious users who can supply a carefully crafted string that overflows the fixed length array in such a way that the security of the system is compromised. This is still the most common exploit in fielded C code today. In attempting to overcome the buffer overflow problem, some programmers try to limit the number of characters that are copied. This can result in strings being improperly truncated. This, in turn, results in a loss of data which may lead to a different type of software vulnerability.
A special case of truncation error is a termination error. Many of the standard C string functions rely on strings being null terminated. However, the length of a string does not include the null character. If just the non-null characters of a string are copied then the resulting string may become improperly terminated. A subsequent access may run off the end of the string and corrupt data that should not have been touched.
Finally, inadequate data sanitization can also lead to vulnerabilities. Many applications require data to be constrained not to contain certain characters. Very often, malicious users can be prevented from exploiting an application by ensuring that the illegal characters are not copied into the strings destined for the application.
Proposed solution
A secure string library should provide facilities to guard against the problems described above. Furthermore, it should satisfy the following requirements:
Decimal Floating Point Types
I'm off to a meeting of the ISO/SC22/WG14, the C programming language committee meeting in a couple of weeks. One of the papers on the agenda (N1154) is a proposal for a Technical Report on adding Decimal Floating Point types and arithmetic to the C programming language specification. The proposal is based on a model of decimal arithmetic which is a formalization of the decimal system of numeration (Algorism) as further defined and constrained by, IEEE-854, ANSI X3-274, and the proposed revision of IEEE-754 (known as IEEE-754R).
The proposal adds decimal floating point within the type hierarchy, as base types, real types and arithmetic types. The three types are called:
double f;
f = 0.1;
Finding a dynamic library dependency
At a customer visit this week I was asked if the compiler libraries can be reshipped with an application. And of course the answer is yes. A complete list of those libraries can be found at:
/opt/SUNWspro/READMEs/runtime.libraries
This reminded me of another question about how an application can locate library dependencies when the application can be installed in a user defined location. For example, you have an application whose dynamic library is always located relative to itself via the path ../lib, like this:
cobol% ls -laF bin prod prod/bin .
.:
total 48
drwxr-xr-x 4 bin bin 512 Mar 6 08:15 ./
drwxrwxrwx 5 bin bin 1024 Mar 5 10:23 ../
drwxr-xr-x 2 bin bin 512 Mar 5 10:37 bin/
-rw-r--r-- 1 bin bin 2178 Mar 6 08:15 myapp.c
drwxr-xr-x 3 bin bin 512 Mar 5 10:37 prod/
bin:
total 6
drwxr-xr-x 2 bin bin 512 Mar 5 10:37 ./
drwxr-xr-x 4 bin bin 512 Mar 6 08:15 ../
lrwxrwxrwx 1 bin bin 20 Mar 5 10:37 myapp -> ../prod/bin/myapp
prod:
total 6
drwxr-xr-x 3 bin bin 512 Mar 5 10:37 ./
drwxr-xr-x 4 bin bin 512 Mar 6 08:15 ../
drwxr-xr-x 2 bin bin 512 Mar 6 08:15 bin/
drwxr-xr-x 2 bin bin 512 Mar 6 08:15 lib/
prod/bin:
total 4
drwxr-xr-x 2 bin bin 512 Mar 6 08:15 ./
drwxr-xr-x 3 bin bin 512 Mar 5 10:37 ../
-rwxr-xr-x 1 bin bin 8972 Mar 6 08:33 myapp*
prod/lib:
total 4
drwxr-xr-x 2 bin bin 512 Mar 6 08:15 ./
drwxr-xr-x 3 bin bin 512 Mar 5 10:37 ../
-rwxr-xr-x 1 bin bin 8972 Mar 6 08:33 mylib.so*
cobol%
The linker provides Dynamic String Tokens that can be used to when creating the application. In this case the token is called: $ORIGIN
And would be used as follows:
% cc -o prod/bin/myapp myapp.c '-R$ORIGIN/../lib' -L prod/lib -lmylib
For details about $ORIGIN and other Dynamic String Tokens see the Linker and Libraries Guide on docs.sun.com.
IPL32 to LP64, Number One Porting Issue
ILP32 - integer, long, and pointer types are 32-bits in size
LP64 - long and pointer types are 64-bits in size, int remains 32-bitsin size
What's the number one issue with porting 32-bit application (ILP32) to a
64-bit environment (LP64)?
Catching security vulnerabilities in C code
Check out what Sun Studio C compiler has provided for detect coding practices that could lead to security vulnerabilities. Specifically, Sun added security vulnerability checking to lint, the C program checker.
Below is an overview of the flag to specify on the lint command to obtain security vulnerability checking. And here is a testimonial about how it is used in the Solaris sources.
-errsecurity=v
lint -errsecurity=core
Checks for source code constructs that are almost always either unsafe or difficult to verify. Checks at this level include:
Consider source code that produces warnings at this level to be abug. The source code in question should be changed. In all cases, straightforward safer alternatives are available.
lint -errsecurity=standard
Includes all checks from the core level plus constructs that may be safe, but have better alternatives available. This level is recommended when checking newly-written code. Additional checks at this level include:
Replace source code that produces warnings at this level with new or significantly modified code. Balance addressing these warnings in legacy code against the risks of destabilizing the application.
lint -errsecurity=extended
Contains the most complete set of checks, including everything from the Core and Standard levels. In addition, a number of warnings are generated about constructs that may be unsafe in some situations. The checks at this level are useful as an aid in reviewing code, but need not be used as a standard with which acceptable source code must comply. Additional checks at this level include:
Review source code that produces warnings at this level to determine ifthe potential security issue is present.
Suns's compilers have previewed on linux, take a look here http://developers.sun.com/prodtech/cc/linux_index.html.
This is just a preview, we have a long way to go before we can or will make this a product offering. On the way to doing that we got some feed back on the SDN, that our c89 command should work like the c89 command encountered on Linux.
Specifically, the following simple test case gets an error using the c89 command from Sun:
long long foo;
But the c89 command on linux accepts this declaration.
Why does the c89 (/bin/c89) command on linux allow this? It makes no sense at all, the entire purpose of the c89 command is to provide a portable compilation environment to those conforming to SUSv3. SUSv3 support the 1994 ISO C standard. long long is not an allowed type in the ISO 1994 C standard.
Sun is porting it's compiler from Solaris it Linux. On Solaris, Sun supports SUSv2 which defines the c89 command. We implement the c89 command by being pedantic about the 1994 C ISO language as required by SUSv2, and thus long long must not be accepted as a legal type. There are conformance tests that check this, and you cannot pass them without producing an error message.
We can change the error message into a warning and thus pass the conformance test and still present a consistent interface across Solaris and Linux.
But what we do not yet understand, is why /bin/c89 on linux does not produce even a warning message for the above program ...
Printing C language Complex and Imaginary numbers
_Complex & _Imaginary in the
absense of <complex.h>.
_Complex types have the same alignment and size of a two element array of the corresonding real type.
_Imaginary types have the same alignment and size of the corresponding real type.
_Complex and
_Imaginary numbers. However new functions
cimag() and creal() are available in
<complex.h> to retreive the real and imaginary
parts as their corresponding real floating point types. Note you cannot
pass an _Imaginary= number to %f because
_Imaginary will not be promoted to the double that
%f expects. You must spoof the type via a pointer.
Below is a non-portable way to print _Complex &
_Imaginary in the absense of <complex.h>.
% more t.c
#include <stdio.h>
#define str(s) #s
#define xstr(s) str(s)
#define T float
#define CRe(T, z) ((T *) &z)[0]
#define CIm(T, z) ((T *) &z)[1]
#define Im(T, z) ((T *) &z)[0]
int
main(void) {
T _Complex a = 3.0F + 4.0F * _Imaginary_I;
T _Imaginary b = a;
T g;
g = (T) a;
(void) printf("g=(" xstr(T) ")(%f, %f)=%f \n",
CRe(T, a), CIm(T, a), g);
(void) printf("_Imaginary b = (%f)\n", Im(T, b));
return(0);
}
% cc t.c
% a.out
g=(float)(3.000000, 4.000000)=3.000000
_Imaginary b = (4.000000)
%
( Jun 12 2005, 08:24:41 PM PDT )
Permalink
Comments [0]