From kragen@dnaco.net Fri Sep 11 14:48:04 1998 Date: Fri, 11 Sep 1998 14:48:02 -0400 (EDT) From: Kragen To: richard.harlan@convergys.com cc: Kragen , clug-user@clug.org Subject: Re: life depending on code (was Re: Story about a literary culture of Unix) In-Reply-To: <8525667C.00649549.00@notes.cbis.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Keywords: X-UID: 1856 Status: O X-Status: On Fri, 11 Sep 1998 richard.harlan@convergys.com wrote: > Kragen wrote: > >On Fri, 11 Sep 1998, Bradley M. Kuhn wrote: > >> If they were Access types. > >> > >> They aren't. They can't be. You can forbid pointer arithmetic, but a > >> clumsy programmer might do it by accident... > > > >It's quite possible to modify gcc to refuse to compile code with > >pointer arithmetic in it. > > I'm no expert on programming languages, but it appears to me that the > problem with C (in re pointers) is fundamental and not a matter of an > enumerable set of features. C is way too close to the machine for the kind > of fault tolerant programming that this thread is concerned with[0]. If "j > = *(ptr + i);" is prevented, I can still do "j = ptr[i];". Yes, but that would be illegal, because it's pointer arithmetic. All access to arrays would go through special "exempt" functions that did bounds-checking. The gcc extensions to do bounds-checking on unmodified code do essentially this, but they put the bounds-checks inline (and sometimes, I imagine, can even move them out of loops and such). > The C library is > also full of direct access to memory addresses; consider everything that > can be done with memcpy, strncat and so on. You'd have to rewrite those to do bounds-checking. > I might also add that C and C++ allow just plain brain-dead type casts. You > can cast a pointer to simple data type to a pointer to a struct (maybe to > allow it to be stored in an array of structs), then later access a struct > member that's offset 12 or 20 (or 500) bytes, and "ker-blam!" Troo. (The gcc extensions cover that, too.) > What's needed is a layer abstraction over the whole system of data types > that would prevent a "pointer" from accessing a real (physical or virtual) > machine address. I know that some languages support this, but I can't name > one myself. C. :) Also, of course, Perl, Lisp, Scheme, Tcl, Java, Python, REXX, sh, etc. > . . . not to mention that > core files are very convenient for debugging non-life-threatening > applications. When the program segfaults and dumps core, I don't even have > to diff the output against the test case--it failed! Not to mention that I > can just look at the stack trace-back and say, "Hey Bob, you've got a > segfault in fooBar ()!" Well, the question is, if it was impossible to make segfaults, what would happen instead? With bounds-checking extensions to C (or bounds-checked arrays, like in the other languages I mentioned) you get an error message that tells you what the problem is. (Garbage collection plus bounds-checking equals pointer security. Bounds checking by itself will still leave some segfaults.) A segfault is a different matter altogether. fooBar() may have segfaulted for any of the following reasons: - It did something stupid. - Its caller passed it a NULL pointer that it dereferenced. - Its caller passed it a pointer to something that had already been freed. (You need garbage collection to solve this.) - It called a routine with a wild pointer error that overwrote some pointer with garbage, and then it dereferenced the garbage pointer. - Variant: it dereferences a pointer that had been previously overwritten with garbage by some long-dead routine. - Its caller passed it a garbage pointer (say, one that was uninitialized and usually NULL) that it dereferenced. Worse, most of those things will *not* segfault most of the time. Bounds-checking is unquestionably better when binary compatibility and the time to develop the compiler are not constraints. Kragen -- Kragen Sitaker The sages do not believe that making no mistakes is a blessing. They believe, rather, that the great virtue of man lies in his ability to correct his mistakes and continually make a new man of himself. -- Wang Yang-Ming