C undefined behavior fix
<<One of the reasons why C is a good language for the kernel is that its memory model is a good match to the memory organization used by the processors that linux runs on. Thus, for these processors, adding an offset to a pointer is in fact simply an arithmetic addition. Combine that with the fact that the kernel is far more aware of how stuff is laid out in its virtual memory space than most C programs, and you can see that it is reasonable for the kernel to do pointer arithmetic which might be undefined according to the strict letter of the law, but which in fact works correctly on the class of processors that Linux runs on, for all reasonable compiler implementations.
Quoted 1 line
Quoted 1 line
The concept of "all reasonable compiler implementations" is a very dubious one. There is nothing to stop a valid C compiler from building assertions based on the quoted paragraph from the C standard, e.g. it could derive valid range information from knowing that an offset was constrained to certain limits. So writing bogus C like this is risky, and as compilers get more sophisticated, one is likely to hear screams, but they are not justified in my opinion. There is no excuse for such abuse.
Quoted 7 lines · Robert Dewar
The concept of "all reasonable compiler implementations" is a very dubious one. There is nothing to stop a valid C compiler from building assertions based on the quoted paragraph from the C standard, e.g. it could derive valid range information from knowing that an offset was constrained to certain limits. So writing bogus C like this is risky, and as compilers get more sophisticated, one is likely to hear screams, but they are not justified in my opinion. There is no excuse for such abuse.
There is already such a project under development: see
http://gcc.gnu.org/projects/bp/main.html
This is a modification to gcc that implements pointers as triples. While there is a performance penalty for doing this, it can completely eliminate the problem of exploitable buffer overflows. However, programs that violate the rules of ISO C by generating out-of-range pointers will fail.
Quoted 9 lines · Joe Buck
There is already such a project under development: see
http://gcc.gnu.org/projects/bp/main.html
This is a modification to gcc that implements pointers as triples. While there is a performance penalty for doing this, it can completely eliminate the problem of exploitable buffer overflows. However, programs that violate the rules of ISO C by generating out-of-range pointers will fail.
What will it do if I cast a pointer to unsigned long? Or if I cast an unsigned long to a pointer? The kernel does both of these things, and in a lot of places.
Part of my beef with what gcc-3 is doing is that I take a pointer, cast it to unsigned long, do something to it, cast it back to a pointer, and gcc _still_ thinks it's knows what I am doing. It doesn't.
Paul.
Quoted 10 lines
Quoted 9 lines
There is already such a project under development: see
http://gcc.gnu.org/projects/bp/main.html
This is a modification to gcc that implements pointers as triples. While there is a performance penalty for doing this, it can completely eliminate the problem of exploitable buffer overflows. However, programs that violate the rules of ISO C by generating out-of-range pointers will fail.
Quoted 3 lines
What will it do if I cast a pointer to unsigned long? Or if I cast an unsigned long to a pointer? The kernel does both of these things, and in a lot of places.
Perhaps you need to reread a book like K&R, second edition, to find out what the C language promises you and what it doesn't.
The bounded-pointer approach represents a C pointer as three machine pointers. When you cast to unsigned long, it converts the "value" pointer. When you cast an unsigned long to a pointer, you lose the range information, so the pointer's extent is anywhere in memory. However, if the compiler can determine by dataflow analysis where this value came from it is entitled to put the original range information back.
Quoted 4 lines
Part of my beef with what gcc-3 is doing is that I take a pointer, cast it to unsigned long, do something to it, cast it back to a pointer, and gcc _still_ thinks it's knows what I am doing. It doesn't.
The C language standard defines quite precisely what the compiler is allowed to assume and what it is not allowed to assume. If you don't like these rules, you will dislike *all* modern C compilers, especially the expensive proprietary C compilers hardware vendors often use to get good SPEC results.