When the crypto/ssl targets attempt to build their shared libs, they run:
        cd ..; make libcrypto.so.1.0.0
The top level Makefile in turn runs the build-shared target for that lib.

The build-shared target depends on both do_$(SHLIB_TARGET) & link-shared.
When building in parallel, make is allowed to run both of these.  They
both run Makefile.shared for their respective targets:
do_$(SHLIB_TARGET) ->
        link_a.linux-shared ->
        link_a.gnu ->
        ...; $(LINK_SO_A) ->
        $(LINK_SO) ->
        $(SYMLINK_SO)
link-shared ->
        symlink.linux-shared ->
        symlink.gnu ->
        ...; $(SYMLINK_SO)

The shell code for SYMLINK_SO attempts to do a [ -e lib ] check, but fails
basic TOCTOU semantics.  Depending on the load, that means two processes
will run the sequence:
        rm -f libcrypto.so
        ln -s libcrypto.so.1.0.0 libcrypto.so

Which obviously fails:
        ln: failed to create symbolic link 'libcrypto.so': File exists

Since we know do_$(SHLIB_TARGET) will create the symlink for us, don't
bother depending on link-shared at all in the top level Makefile when
building things.

Reported-by: Martin von Gagern <[email protected]>
URL: https://bugs.gentoo.org/545028
---
 Makefile.org | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Makefile.org b/Makefile.org
index 890bfe4..576c60e 100644
--- a/Makefile.org
+++ b/Makefile.org
@@ -350,7 +350,10 @@ link-shared:
                libs="$$libs -l$$i"; \
        done
 
-build-shared: do_$(SHLIB_TARGET) link-shared
+# The link target in Makefile.shared will create the symlink for us, so no need
+# to call link-shared directly.  Doing so will cause races with two processes
+# trying to symlink the lib.
+build-shared: do_$(SHLIB_TARGET)
 
 do_$(SHLIB_TARGET):
        @ set -e; libs='-L. $(SHLIBDEPS)'; for i in $(SHLIBDIRS); do \
-- 
2.3.4


_______________________________________________
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

Reply via email to