On Feb 5, 2015, at 12:59, Junio C Hamano wrote:
I do not know (and I am not quite sure if I want to know) how
serious your "potential" problems would be, and I do not doubt you
know OS X quirks much better than I do and do not intend to argue
there aren't such problems. I am just curious how "user-facing"
comes into the picture.
Suppose you have built and installed some software to /usr/local and
it's ended up in the usual subdirectories, /usr/local/bin, /usr/local/
lib, etc.
Now you get an installer for package X, and to avoid stepping on
things it installs to /opt/XYZ with the usual suspects /opt/XYZ/bin, /
opt/XYZ/lib. There are several of these that I'm aware of where XYZ
is whatever package you're installing.
Now since /opt/XYZ/bin is not usually in one's PATH it installs a few
select symlinks from /usr/local/bin/whatever to /opt/XYZ/bin/
whatever. Not all of the /opt/XYZ installers do this, for some of
them it's a selectable option.
So now we have:
# This one can be a relative or absolute symlink, doesn't matter
/usr/local/bin/foo -> /opt/XYZ/bin/foo
And we also now have this:
# A real binary, not a symlink
# Uses and locates libfoo with ../lib/libfoo.dylib
/opt/XYZ/bin/foo
# A real library binary, not a symlink
/opt/XYZ/lib/libfoo.dylib
So /opt/XYZ/bin/foo locates libfoo.dylib by using a relative path
embedded within it (in this case it would be @loader_path/../lib/
libfoo.dylib).
So far, so good, right?
Nothing complicated going on.
But the user has built and installed an older version of libfoo
already to /usr/local/lib/libfoo.dylib.
Ah-oh.
User attempts to run foo.
Shell finds foo at /usr/local/bin/foo and runs it.
The dynamic linker correctly loads /opt/XYZ/bin/foo and starts to
resolve the dynamic library links embedded in it.
For the "@loader_path/../lib/libfoo.dylib" one it first tries /usr/
local/bin/../lib/libfoo.dylib rather than /opt/XYZ/bin/foo/../lib/
libfoo.dylib because /usr/local/bin/foo was the executable that was
run and since the user has installed an older version of libfoo.dylib
in /usr/local/lib, it finds and loads that instead of the intended
one. If it didn't find that it would then try /opt/XYZ/bin/foo/../lib/
libfoo.dylib and get the right one.
Sometimes you get an immediate error if the unintended library version
is just too old to be compatible. On the other hand, if it's just old
enough to be buggy but not version incompatible now you're running
with a buggy library or some other incompatibility that doesn't show
up right away.
I think this is a nasty bug specific to OS X, the fact that it tries
both paths though suggests it was deliberate.
I have not tested all versions of OS X to see if it might have been
fixed in the latest, but there it is.
If you put /opt/XYZ/bin directly in the PATH this can't happen
(provided /opt/XYZ/bin/foo is not itself a symlink).
So that's how a user-facing binary that is a symlink can cause
problems. I suppose it's not just limited to user-facing binaries,
but that's where it tends to show up as it seems the non-user-facing,
non-executable stuff usually has a sufficiently controlled surrounds
that they're not vulnerable.
I say "user-facing" because the binary is found in the user's $PATH.
I do not consider the libexec/git-core binaries to be user-facing
since they are not normally in the user's $PATH but rather normally
accessed via the "git" binary which is likely in the user's $PATH.
In the case of Git, a /usr/local/bin/git -> ../libexec/git-core/git
symlink should not be vulnerable to this problem, because even if the
executable ends up with some relative dylib paths in it (usually not
the case) when applied to /usr/local/bin they're unlikely to lead
anywhere with user-installed libraries since git-core is one directory
deeper than bin.
Anyhow, that's why I tend to avoid putting symlink-to-binary stuff in
PATH. In any case a packager can make adjustments to avoid the
problem before creating an installer.
-Kyle
P.S.
On Feb 5, 2015, at 12:59, Junio C Hamano wrote:
I'm not sure exactly why, but I think:
On Jan 30, 2015, at 13:10, Junio C Hamano wrote:
That would make me feel dirty.
That is a confusing style of quoting. I suspect that I said the
above in a totally different context.
But I've been dying to work that in somehow ever since I saw that. ;)
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html