Is it possible to dynamically load a @safe function from a shared library ?

Steven Schveighoffer schveiguy at gmail.com
Sun Mar 15 16:48:26 UTC 2020


On 3/14/20 6:06 AM, wjoe wrote:
> On Friday, 13 March 2020 at 20:31:16 UTC, Steven Schveighoffer wrote:
>> On 3/13/20 4:22 PM, wjoe wrote:
>> I would expect that something could be written to turn a signature 
>> string into a mangling and also provide the correct type upon return. 
>> Something like:
>>
>> auto f = getFunction!(@safe void function(int))("package.module.symbol");
>>
>> and have it properly mangle the expected function name and pull it 
>> from the dynamic library.
>>
> 
> Thanks for your reply.
> 
> core.demangle: mangle; comes to mind. And in fact, because the exports 
> weren't extern(C), that's how I imported the symbols; prior to reading 
> H. S. Teoh's reply. That's when I realized that I've got a problem.
> 
> Even though I know that the function being exported are all compiled 
> @safe, that doesn't mean I can count on the fact.
> Since a plugin is a separate file it can be swapped out with a version 
> that exports all the same (forged) symbols names but with a @system 
> implementation.
> Forging these symbol names is as easy as something like mangle!(int 
> function(int))("a.b")); (=_D1a1bPFiZi) and copy/pasting that into 
> pragma(mangle, "_D1a1bPFiZi") and voila, the loader can nothing but 
> trust that this is true.
> 
> Forging is maybe too hard a word but my vocabulary lacks a better one.

My original point is that forging is possible without using a dynamic 
library. Anyone who has pragma(mangle)'d the symbol can "forge" anything 
they want, it's not that hard.

Even without using pragma(mangle, it's possible):

mod1.d:

__gshared someGlobal;
extern(C) void realImpl() // no mangling
{
    someGlobal = 5; // yay side effects!
    *(cast(ubyte*)0xdeadbeef) = 5; // yay no safety!
    throw new Exception("yay, I can throw!");
}

mod2.d:

extern(C) void realImpl() @safe pure nothrow;

void foo() @safe pure nothrow // mangled properly
{
    realImpl();
}

So why worry about the dynamic library case? I would say if you obey the 
mangling rules, the compiler should trust the mangling.

-Steve


More information about the Digitalmars-d-learn mailing list