[loader] resolve symlinks when looking for an image in the loaded_images cache
authorAleksey Kliger <aleksey@xamarin.com>
Tue, 9 May 2017 21:56:03 +0000 (17:56 -0400)
committerAleksey Kliger (λgeek) <akliger@gmail.com>
Wed, 10 May 2017 14:57:18 +0000 (10:57 -0400)
Consider the old code (which just used mono_path_canonicalize)

Suppose foo.dll is a symlink to bar.dll

Suppose we've try to load foo.dll the first time:
do_mono_image_open is passed "foo.dll" it then sets image->name to "bar.dll"
which is then used by register_image to do a lookup and then inserts the
mapping from "bar.dll" to the new image (call it Image1).

Suppose we try to load foo.dll a second time:
we check for "foo.dll" in the loaded_images cache and get NULL.
So we call do_mono_image_open ("foo.dll", ...) again, and again image->name is
set to "bar.dll".  (Call this Image2)
We call register_image again which looks up bar.dll and gets Image1.  So it
increments the refcount for Image1 and unloads Image2 and so
mono_image_open_a_lot returns Image1.

With the new code:

The first time we try to load foo.dll everything is the same.  The second time
we try to load foo.dll, we resolve the symlink from "foo.dll" to "bar.dll" in
mono_image_open_a_lot and return Image1 directly from loaded_images.

mono/metadata/image.c

index d332affbdc66640fac7613d2df802c77cac67150..842a7ab59a4f6da05927cd1a2a7ecdb6326b2357 100644 (file)
@@ -1700,7 +1700,7 @@ mono_image_open_a_lot (const char *fname, MonoImageOpenStatus *status, gboolean
        }
 #endif
 
-       absfname = mono_path_canonicalize (fname);
+       absfname = mono_path_resolve_symlinks (fname);
 
        /*
         * The easiest solution would be to do all the loading inside the mutex,