MonoOni / binarydist

Mono Binary Builds for Testing
9 stars 0 forks source link

Runtime allows null dereferences to happen #1

Closed NattyNarwhal closed 6 years ago

NattyNarwhal commented 6 years ago

The runtime seems to allow null dereferences to happen. Can be mitigated with MONO_DEBUG="explicit-null-checks".

using System;
using System.Linq;
using System.Collections.Generic;

class Test {
        static void Broken() {
                Dictionary<int, int> d = null;
                Console.WriteLine(d == null);
                Console.WriteLine(d.Count);
        }

        static void Main() {
                Broken();
        }
}

Results, no explicit-null-check:

True
0

Results, with

True

Unhandled Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
  at Test.Broken () [0x0000b] in <a7059fdc15e2483886edcd43bef97db4>:0
  at Test.Main () [0x00000] in <a7059fdc15e2483886edcd43bef97db4>:0
[ERROR] FATAL UNHANDLED EXCEPTION: System.NullReferenceException: Object reference not set to an instance of an object.
  at Test.Broken () [0x0000b] in <a7059fdc15e2483886edcd43bef97db4>:0
  at Test.Main () [0x00000] in <a7059fdc/opt/mono/bin/mono test.exe    

Another good example would be to access the "Keys" members of a Dictionary - this can expose issues with gshared, which can be disabled with --optimize=-gshared.

NattyNarwhal commented 6 years ago

Null dereferences may be happening because AIX/i have page 0 mapped in anyways?

IIRC, the way Mono handles NREs is catching SIGSEGVs in managed code. If it's accessing "valid" memory....

If that's the case, then there's two options:

  1. make 0x0 invalid for us, allowing for it to SIGSEGV (say, mprotect it)

  2. somehow set that optimization to be mandatory for AIX/i

NattyNarwhal commented 6 years ago

Option 1 is invalid; mmap/mprotect will throw ENOMEM if we try to map 0x0.

NattyNarwhal commented 6 years ago

mono/mono#7300 filed.

NattyNarwhal commented 6 years ago

Resolved upstream.

NattyNarwhal commented 6 years ago

That being said, there are some cases when it can jump to 0x0 it seems? Roslyn might be triggering such a case.