dlsym(RTLD_DEFAULT, "getentropy") return non-NULL on Mac

Wang Weijun weijun.wang at oracle.com
Sun Nov 8 00:37:16 UTC 2015


> On Nov 8, 2015, at 4:29 AM, Dmitry Samersoff <dmitry.samersoff at oracle.com> wrote:
> 
> Wang Weijun,
> 
> 1. RTLD_DEFAUL call is expensive and dangerous because it cause symbol
> search across all loaded images. So it can pick up something absolutely
> irrelevant to your expectations at any time.
> 
> If you decide to play to this game, you have to use dladdr to check the
> origin of a symbol and try to guess whether it is what you are looking
> for or not.
> 
> Please dlopen(libSystem.dylib, RTLD_NOW) and search through it only.
> 
> 2. You shouldn't rely on return value of dlopen() or dlsym(). Call
> dlerror() and check whether it returns error or NULL.

I'll try.

> 
> PS:
>  What is the goal of using a get entropy ?

The function is rather new in the latest Solaris beta [1] and it's preferred to reading from /dev/random. There are already people suggest adding it to Linux. If I use simply using dlsym then it will automatically work on all current and future platforms. In fact, I was planning to write

    getentropy = (GETENTROPY_FN)dlsym(RTLD_DEFAULT, "getentropy");
    if (getentropy) {
        return 1;
    } else {
    	getrandom = (GETRANDOM_FN)dlsym(RTLD_DEFAULT, "getrandom");
    	if (getrandom) {
            return 2;
    	} else {
            return -1;  // will read /dev/random
        }
    }

Thanks
Max

[1] https://blogs.oracle.com/darren/entry/solaris_new_system_calls_getentropy

> 
> -Dmitry
> 
> On 2015-11-07 05:51, Wang Weijun wrote:
>> I find something strange.
>> 
>> Background: a new method getentropy() is available on OpenBSD [1] and Solaris and people are also proposing it on other OSes.
>> 
>> Therefore inside JDK I write a piece of native code to detect it, something like
>> 
>>    typedef int (*GETENTROPY_FN)(char* buffer, int len);
>> 
>>    getentropy = (GETENTROPY_FN)dlsym(RTLD_DEFAULT, "getentropy");
>>    if (getentropy) {
>>        return 1;
>>    } 
>> 
>> On Mac, it returns non-NULL, but a later call to (*getentropy)(cbuffer, length) shows
>> 
>>  #  SIGBUS (0xa) at pc=0x0000000103bfa030, pid=22434, tid=5891
>>  ...
>>  # Problematic frame:
>>  # C  [libj2rand.dylib+0x1030]  getentropy+0x0
>> 
>> However, "man getentropy" does not show anything, and the following simple program also prints out 0x0
>> 
>> #include <dlfcn.h>
>> #include <stdlib.h>
>> 
>> main() {
>>   void* g = dlsym(RTLD_DEFAULT, "getentropy");
>>   printf("%p\n", g);
>> }
>> 
>> What does this mean? Is the JDK code loading another getentropy() somewhere else? How do I detect it and what shall I do to avoid it?
>> 
>> Thanks
>> Max
>> 
>> [1] http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2
>> 
> 
> 
> -- 
> Dmitry Samersoff
> Oracle Java development team, Saint Petersburg, Russia
> * I would love to change the world, but they won't give me the sources.




More information about the security-dev mailing list