On 28/09/16 03:25 PM, Thorsten Glaser wrote:
Jack Bates dixit:
A) Call dlsym() early, before anything calls open(). Not possible
  because even if you managed to call dlsym() before anything else,
  dlsym() itself might call open() before it was done initializing :-(

B) Avoid dlsym() altogether. What are the options in this case?

  1) Use sys_open() instead of dlsym(RTLD_NEXT, "open)

How about a combination of both?

Something like this (pseudo code, mostly):

static void initialise_open(void) __attribute__((__constructor__));

static uint8_t open_initialised = 0;

int
open(const char *path, int flags, mode_t mode)
{
        if (!open_initialised)
                return (sys_open(path, flags, mode));
        /* current code with dlsym’s result */
}

static void
initialise_open(void)
{
        /* call dlsym, which is now allowed to call open() */
        /* store its result */
        open_initialised = 1;
}


Of course, I probably ought to better go to bed, but someone
might make something off this. Also, completely untested, modulo
that I have an application in which these constructors work, in
plain GCC (no C++).

My intuition is that not having one consistent implementation might be surprising to callers of open(), however your solution is AS-safe and minimizes the change from the current behavior. Do you know of or anticipate any cases where implementing open() with sys_open() instead of dlsym(RTLD_NEXT, "open") would cause a problem?

Reply via email to