

Dereferencing NULL Pointer, without a Seg Fault - a-priori
http://blog.8thlight.com/dariusz-pasciak/2012/07/03/dereferencing-null-pointer-without-a-seg-fault.html

======
eridius
Misleading headline and final sentence. The whole point of the article is that
it's _not_ dereferencing NULL. It's just passing NULL as a hidden parameter to
a function, which in turn ignores that parameter.

I also found it rather odd that the author spent so much time defining what a
pointer is and what dereferencing is, when the article won't be of any
interest whatsoever to someone who doesn't already know these things.

And lastly, when I saw the headline about dereferencing NULL, I expected it to
be a discussion regarding the circumstances in which you can actually map
address 0 to valid memory (and therefore dereference NULL without crashing),
and the consequences thereof.

~~~
sharkbot
Or the author could have added 'virtual' to the method declaration and
discussed why that code now crashes due to a NULL dereference...

~~~
repsilat
It's disappointing that this works so reliably, even with the simplest of
examples. I would have thought that if the compiler could resolve the function
call statically it would do away with the vtable lookup, but neither g++ nor
Clang do so at any level of optimisation.

~~~
klodolph
Well, you see, that would change the behavior of the program. In order for it
to resolve the vtable statically, which it CAN do, it would have to know what
kind of vtable the NULL cowPointer has. And the true answer is that the
program is already wrong once it accesses the vtable.

To put it another way, such an optimizer would transform incorrect programs
into correct programs.

If you write correct programs, the optimization is useless since it only
transforms incorrect programs. If you write incorrect programs, the
optimization is dangerous since it makes it harder for you to figure out that
your program is wrong.

~~~
repsilat
> In order for it to resolve the vtable statically, which it CAN do, it would
> have to know what kind of vtable the NULL cowPointer has.

Yeah. In retrospect my point doesn't really make any sense at all. Not sure
what I was thinking there.

------
repsilat
According to [1] this is (strictly speaking) undefined behaviour. It also
won't work with virtual function calls, because they'll try to access the
vtable and segfault.

If your compiler isn't cheeky you can use this stuff in funny ways with
constructs like `if(this)` in your member functions. Technically such a check
could be optimised out because `this==null` can only result from undefined
behaviour, but in practice it probably won't be.

1: [http://stackoverflow.com/questions/2474018/when-does-
invokin...](http://stackoverflow.com/questions/2474018/when-does-invoking-a-
member-function-on-a-null-instance-result-in-undefined-beha)

------
prophetjohn
This reminds me of a conversation I had with a coworker recently about how
possible it would be a for an object to check itself for null. Based on this
explanation, it seems like this would definitely be possible in C++ (our
conversation was in the context of Java, but it's interesting from an academic
perspective)

    
    
        class NullChecker {
        public:
          bool isNull() { return !!this; }
        };
    
        int main() {
          NullChecker *nc = 0;
          if(nc->isNull()) doSomething();
          return 0;
        }
    

Forgive my C++ syntax as it's been a while, but this seems like it would work
to me.

~~~
z92
Tried it. It works.

Technically I look at methods as functions with a hidden first parameter that
accepts a pointer to the class object's data. If you don't try to dereference
that pointer, then the function should work like static member.

I was wondering if the compiler will add some check code preventing me from
calling any method on a NULL pointed obj. But obviously its permitting it.

Of course virtual methods are different. Then you are calling a pointer to a
function, the address of which should be stored in your obj data structure.

------
alttab
Actually, the last example won't even run because cout doesn't have the >>
stream operator. Not sure how identical code samples in the same article could
get those mixed up, unless the author typed each example out manually.

Not really contributing to the conversation, but it jumped out at me.

------
zwass
Seems to me that the NULL pointer is never dereferenced...

------
DannyBee
Fun fact: There are a number of platforms that made NULL dereference valid
(usually returning zero), because it enables you to do fun compiler
optimizations that are not safe otherwise. Some of these optimizations relate
to being able to insert new loads or hoist existing ones, some of these relate
to being able to remove null pointer checks. (for example, in:

    
    
      int **a = NULL;
      int *b = NULL;
      int c = 0;
      ...
      if (a ! = NULL)
         b = *a;
      if (b != NULL)
         c = *b;
    

you can remove all the NULL checks if *NULL = 0)

AIX was an example of such a platform (at least until version 5.3, i haven't
used it since then).

------
darkstalker
thought the article was gonna conclude doing something like:

    
    
      void Cow::milk()
      {
          if (!this) throw std::runtime_error("NULL isn't a cow!");
          // rest of the code
      }

------
rayiner
TL;DR version: the '->' operator is punned in C++ to mean both "load through a
pointer" and "call a function with the pointer as the first argument."
Unsurprisingly, nothing blows up when you use the second form with a null
pointer.

V8 actually uses this to implement a pretty cool trick. V8 objects are tagged
--tag bits distinguish valid pointers from integer immediate values. The
integer class has no data, it stores its information in the 'this' pointer.

~~~
mkopinsky
This V8 business sounds like some form of black magic. Do you have more info
on this?

------
Tuna-Fish
I was expecting mmap(1, ...).

Of course, I don't think that works on modern systems anymore, with
vm.mmap_min_addr and friends.

------
chollida1
I'd pointed this out in stackoverflow a few years ago as an example of what
not to do:)

[http://stackoverflow.com/questions/1640309/c-static-
members-...](http://stackoverflow.com/questions/1640309/c-static-members-in-
class/1640619#1640619)

------
xfs
For an actual NULL pointer dereference resulting in arbitrary code execution:
CVE-2009-0385.

~~~
smsm42
Well, technically it's not a NULL pointer dereference, it's (NULL+user
controlled data) pointer dereference, which is quite a different matter. See
e.g.
[http://www.securityfocus.com/archive/1/archive/1/500514/100/...](http://www.securityfocus.com/archive/1/archive/1/500514/100/0/threaded)
for the explanation of the code.

------
lmm
I've come to prefer the python style of object methods, where "self" is an
explicit first parameter; it makes it a lot clearer what's going on.

------
daemonize
I think showing the actual disassembly would help people understand. it might
lose some so maybe as a side bar.

~~~
danellis
Showing some C-like pseudo-code would probably do the trick nicely.

~~~
malkia
p->m() ~= m(p) - e.g. the object is pushed as the first argument to the
method.

The actual "m" is found by looking at the "p" class if it's non-virtual, and
at the "v-table" in p if it's "virtual".

If "m" is static, no class lookup, or object v-table lookup is done, and the
call is p->m() ~= m()

------
sporx
/facepalm

