[lsb-discuss] Best-effort dynamic linking -- take 1
Alexey Khoroshilov
khoroshilov at ispras.ru
Mon Jul 21 02:17:02 PDT 2008
Jeff Licquia wrote:
> Alexey Khoroshilov wrote:
>> If we do not consider the "/proc" topic, the main problem of this
>> implementation is that it does not actually implement re-exec of an
>> application with the lsblinker when required. It just call
>> execv("/proc/self/exe",argv) that leads to cyclic execution of
>> _lsb_init().
>
> Good catch. I had done a "simple" implementation, intending to make
> it work better later, and forgot.
>
> This should have been caught in my testing, though; I thought I had
> tested the case where the new linker was needed. So it looks like
> I'll have to figure out why my test didn't busy-loop forever.
>
>> There are also some other issues, which are pointed below.
>
>> char *argv[128]; // COMMENT: 1024/128
>> limitations have to be fixed in production version.
>
> Do you think it's sufficient to simply declare argv to be 1024 members
> long?
Using any fixed size buffers may lead to undesirable consequences.
At least we should check if an overflow happens and warn users explicitly.
>> S_ISLNK(lsblinker.st_mode)) // WRONG: If lsblinker is
>> a symbolic link, proceed with the nativelinker.
>> // SHOULD BE(?): If
>> lsblinker is not a symbolic link, re-exec.
>> // (May be we also should
>> support a hard link to nativelinker?)
>
> I (attempt to) support that with the code following.
>
>> if (lsblinker.st_ino == nativelinker.st_ino) // WRONG: lstat() sets
>> st_ino of symlink itself instead of the file that it refers to.
>> return;
>
> Correct, except that we've already determined that the LSB linker is
> not a symlink; if it was, we would have exited above. If the file is
> not a symlink, stat() and lstat() act identically.
Yes, the thing that was not clear here is why we should exit (i.e.
proceed with the nativelinker) if the LSB linker is a symlink.
>> pos = cmdbuf;
>> while (*pos && argc < 128) { // WRONG: 1. Invalid
>> assumption that cmdbuf initialized by zeros.
>> argv[argc++] = pos; // 2. Buffer
>> overflow.
>> while (*(++pos)) ;
>> pos++;
>> }
>> argv[argc] = NULL;
>
> Hmm, not sure about this. The null bytes are contained in
> /proc/self/cmdline, so they should be pulled in with the read().
After reading the last argument "while (*pos && argc < 128)"
dereferences the pos element, which is the next after the last written
by read(). And it is zero only if cmdbuf was initialized by zeros. Also
if size of "/proc/self/cmdline" is 1024 it leads to reading the memory
out of the buffer.
> I do see a potential for problems if /proc/self/cmdline is larger than
> our buffer. Your fix looks good for that, though it also has the side
> effect of using malloc(). Maybe we can do something better with the
> static buffer.
>
>> exit(255); // COMMENT: May be it is
>> better to try to proceed with the nativelinker.
>
> Yup, entirely possible. What do others think?
I am not sure which solution is preferable.
>
>> I have fixed some issues (see the file attached). The remaining
>> questions are:
>> - What is the best way to re-exec an application with the lsblinker?
>
> A few options:
>
> - Read the exe symlink, instead of just exec-ing it.
>
> - Rely on argv[0] and do our own PATH searching, and trust that
> nothing has screwed up the PATH.
>
>> - What is content of "/proc/self/cmdline" in non-POSIX locales?
>
> The "spec" in the kernel documentation is terrible. My guess would be
> that whatever got passed to the exec syscall as the argv array gets
> stuffed into /proc/self/cmdline without locale translation. But we
> should probably look at the kernel code to make sure.
Yes, I suspect that our work with zero bytes may be incorrect in these
cases.
>> - Is it ok to use malloc?
>
> There may be issues with it, since we may be running before the heap
> manager initialization code. I'd like to avoid it if at all possible.
>
As far as I know (not sure) the heap manager initialization code is
executed during // the first invocation of malloc-family functions. At
least, malloc can be called by any C++ constructor, which can be
executed at the similar stage.
>> - Should we support symlink only or hardlinks too?
>
> Yup.
>
> Also:
>
> - Should best-effort be the default for LSB 4 builds?
I would say yes. Of course, if we finish the implementation.
--
Alexey Khoroshilov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.linux-foundation.org/pipermail/lsb-discuss/attachments/20080721/e5cc2104/attachment.htm
More information about the lsb-discuss
mailing list