lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Tue, Feb 15, 2011 at 16:39, Sean Conner <sean@conman.org> wrote:
>
>        I call it my billion-dollar mistake. It was the invention of the
>        null reference in 1965. At that time, I was designing the first
>        comprehensive type system for references in an object oriented
>        language (ALGOL W). My goal was to ensure that all use of references
>        should be absolutely safe, with checking performed automatically by
>        the compiler. But I couldn't resist the temptation to put in a null
>        reference, simply because it was so easy to implement. This has led
>        to innumerable errors, vulnerabilities, and system crashes, which
>        have probably caused a billion dollars of pain and damage in the
>        last forty years.
>                --- C. A. R. Hoare
>
> It was thus said that the Great Axel Kittenberger once stated:
>> julien> -          It is the value given when we don’t know what else
>> to give (not
>> julien> defined, unknown value, an error occured, …)
>>
>> Thank you a lot for bringing that up! In your list it has 3 meanings
>> already, including even an ellipsis for more! Thats whats likely the
>> cause the reappearing confusion around it.
>>
>> I see what I've done here however. _Nobody_ was actually inspired by
>> the idea of non-nilness. I'm suprised that no-one pointed the "this
>> language you never heared of", that has non-nullable types and
>> non-null-pointers. BTW: what does fortran (in its many dialects use?)
>
>  I'm only slightly familiar with Fortran77, having used it briefly in '88
> or '89 (college course and I still have the text book) but there's no
> concept of NULL in Fortran77, which is understandable since you have to
> predeclare everything (including the sizes of all arrays) before you use it.
> Also given that you declare all variable types (by default, variables
> starting with I through N are of type integer, otherwise they're real) there
> is no concept of "undefined" or "unknown" (okay, there *may* be a NaN but I
> find no reference to such in the book I have).  Also, there is no concept of
> pointers in Fortran77, so there is also no concept of a NULL pointer.
>
>> I don't know what to make of it, either the idea is incredibly stupid
>> and a fallback or an anachronism for which we just yet fail to see its
>> virtue.
>
>  There's a program I came across [1] that allows on to map the
> address 0 in a Linux process.  The program allows for both reading and
> writing, but even just making the page(es) read-only makes for some
> interesting possibilities, but first, a bit of a digression---feel free to
> skip the next paragraph if it's too pedantic.
>
>  C states that a 0 in a pointer context, such as:" char *p = 0;" is to be
> converted to a NULL pointer, or an invalid address that cannot be
> referenced.  On *most* platforms, this address also happens to be 0, but it
> *can* be some other bit pattern that makes an invalid address (although I'm
> not aware of any CPU architecture that uses anything other an 0 for an
> invalid address; they can exist, I'm just not aware of any).  It just so
> happens that 0 tends to work across a wide range of modern computers these
> days.  So, assuming that address 0 *is also* an invalid address, we resume.
>
>  In C, strings are character arrays terminated by a 0 byte.  Assuming the
> memory at location 0 is also 0, then
>
>        strcmp(NULL,"") == 0
>        strlen(NULL) == 0
>        printf("%s",NULL) = ""
>
>  And, if you map enough memory at 0, with the contents of 0, to cover the
> size of any structure, then you automatically have a "NULL" object that can
> be passed around, as long as it's not written to.   Too bad you can't map one
> block of memory for read-only access at 0, and a different block of memory
> write-only at 0, for then you would have a truely NULL object, that's always
> empty and yet, writes to it don't do anything (much like /dev/null under
> Unix).
>
>  Some might consider the idea wonderful (and I admit, it's an intriguing
> idea), while others are horrified at the sins (bugs) this hides (as I am).
> But what would the effect of allowing such a "nil" in Lua?
>
>  I know that in the C code I write, I try to avoid NULL as much as
> possible.  It's not always easy, but it does lead to better code in my
> opinion.
>
>  -spc (and no, I don't map address 0 in any of my programs, no matter
>        how tempting it is ... )
>
> [1]
> #define _GNU_SOURCE
> #include <assert.h>
> #include <sys/mman.h>
> #include <stdio.h>
>
> int main()
> {
>  int  *ptr;
>
>  ptr =  mmap(
>        0,
>        4096,
>        PROT_READ | PROT_WRITE,
>        MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
>        -1,
>        0
>  );
>
>  if (ptr == (void *)MAP_FAILED)
>  {
>    perror("Unable to mmap(NULL)");
>    fprintf(stderr, "Is /proc/sys/vm/mmap_min_addr non-zero?\n");
>    return 1;
>  }
>
>  assert(ptr == NULL);
>
>  printf("Dereferencing my NULL pointer yields: %d\n", *ptr);
>  *ptr = 17;
>  printf("Now it's: %d\n", *ptr);
>  return 0;
> }
>
>

While this is straying a bit off topic, you might be interested to
know that mapping address 0 can also lead to security vulnerabilities.
An example is in the Nintendo Wii kernel. The gist of it is, a
function looks up a pointer to a struct, and doesn't check if that
pointer is NULL before reading some pointers from that struct and
writing zero to them.
Normally the NULL dereference would just cause a crash, but the kernel
allowed a userspace program to map address 0, which meant now the
kernel is reading some pointers *they control* and writing zero to
them. The attackers simply inserted the addresses of some critical
instructions in a security routine, taking advantage of the fact that
0 is a NOP instruction...

-- 
Sent from my toaster.