March 14, 2020 Re: Is it possible to dynamically load a @safe function from a shared library ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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.
>
> -Steve
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.
|
March 15, 2020 Re: Is it possible to dynamically load a @safe function from a shared library ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to wjoe | 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
|
March 15, 2020 Re: Is it possible to dynamically load a @safe function from a shared library ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 3/13/20 5:06 PM, H. S. Teoh wrote: > On Fri, Mar 13, 2020 at 04:31:16PM -0400, Steven Schveighoffer via Digitalmars-d-learn 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. > [...] > > This would still have to be @trusted, of course, since there's no > telling what's actually inside the object file. Of course it has to be trusted. The underlying function uses void *. But not because you can't trust the mangling. > But this sort of facility totally should be in Phobos, or at least in > some dub package somewhere. It will make working with dynamically > loaded libraries in D so much more convenient. I'm not really motivated to make such a package, as I don't do any software with runtime loading of libraries. But I bet it would be either accepted into Phobos and/or wouldn't be that hard to add for a library. -Steve |
Copyright © 1999-2021 by the D Language Foundation