Treat symlinks better in $ORIGIN determination in ld.so
authorgnezdo <gnezdo@openbsd.org>
Sun, 9 Apr 2023 23:41:47 +0000 (23:41 +0000)
committergnezdo <gnezdo@openbsd.org>
Sun, 9 Apr 2023 23:41:47 +0000 (23:41 +0000)
Now symlinking an executable away from the rest of its installation
tree no longer prevents it from finding the libraries. This matches
the behavior of other OS linkers. Prompted by a behavior change in
lang/ghc test suite.

Swapped the order of dirname/realpath in _dl_origin_path.

Added some regress tests that pass and then bin3 that fails without
this change and reflects the behavior needd for lang/ghc.

Suggestion by semarie@, OK deraadt@

libexec/ld.so/resolve.c
regress/libexec/ld.so/subst/Makefile
regress/libexec/ld.so/subst/prog2/Makefile [new file with mode: 0644]
regress/libexec/ld.so/subst/prog2/main.c [new file with mode: 0644]

index 272722c..709402d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: resolve.c,v 1.97 2022/01/08 06:49:41 guenther Exp $ */
+/*     $OpenBSD: resolve.c,v 1.98 2023/04/09 23:41:47 gnezdo Exp $ */
 
 /*
  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
@@ -227,15 +227,18 @@ _dl_origin_subst_path(elf_object_t *object, const char *origin_path,
 static int
 _dl_origin_path(elf_object_t *object, char *origin_path)
 {
-       const char *dirname_path = _dl_dirname(object->load_name);
+       const char *dirname_path;
 
-       if (dirname_path == NULL)
+       /* syscall in ld.so returns 0/-errno, where libc returns char* */
+       if (_dl___realpath(object->load_name, origin_path) < 0)
                return -1;
 
-       /* syscall in ld.so returns 0/-errno, where libc returns char* */
-       if (_dl___realpath(dirname_path, origin_path) < 0)
+       dirname_path = _dl_dirname(origin_path);
+       if (dirname_path == NULL)
                return -1;
 
+       _dl_strlcpy(origin_path, dirname_path, PATH_MAX);
+
        return 0;
 }
 
index 580eb59..f15700e 100644 (file)
@@ -1,6 +1,6 @@
-#      $OpenBSD: Makefile,v 1.1 2013/03/30 22:03:51 kurt Exp $
+#      $OpenBSD: Makefile,v 1.2 2023/04/09 23:41:48 gnezdo Exp $
 
-SUBDIR+= libaa prog1
+SUBDIR+= libaa prog1 prog2
 
 install:
 
diff --git a/regress/libexec/ld.so/subst/prog2/Makefile b/regress/libexec/ld.so/subst/prog2/Makefile
new file mode 100644 (file)
index 0000000..3881c67
--- /dev/null
@@ -0,0 +1,38 @@
+# $OpenBSD: Makefile,v 1.1 2023/04/09 23:41:48 gnezdo Exp $
+
+.include <bsd.obj.mk>
+
+AA_DIR=${.CURDIR}/../libaa
+
+AA_OBJDIR!=    if [ -d $(AA_DIR)/${__objdir} ]; then \
+                       echo "$(AA_DIR)/${__objdir}"; \
+               else \
+                       echo "$(AA_DIR)"; \
+               fi
+
+PROG=          prog2
+SRCS=          main.c
+CPPFLAGS+=     -I$(AA_DIR)
+LDADD+=                -laa
+LDFLAGS+=      -Wl,-z,origin,-rpath,'$$ORIGIN/../lib'
+LDFLAGS+=      -L$(AA_OBJDIR)
+
+REGRESS_TARGETS = test
+
+.PHONY: test
+test: $(PROG)
+       mkdir -p lib bin bin2 bin3/bin
+       cp $(AA_OBJDIR)/libaa.so* lib
+       cp ./$(PROG) bin
+       bin/$(PROG)
+       ln -sf ../bin bin2/bin
+       bin2/bin/$(PROG)
+       ln -sf $$(realpath bin/$(PROG)) bin3/bin/$(PROG)
+       bin3/bin/$(PROG)
+
+clean:
+       rm -f a.out [Ee]rrs mklog *.core y.tab.h \
+           ${PROG} ${OBJS} ${_LEXINTM} ${_YACCINTM} ${CLEANFILES}
+       rm -rf lib bin bin2 bin3
+
+.include <bsd.regress.mk>
diff --git a/regress/libexec/ld.so/subst/prog2/main.c b/regress/libexec/ld.so/subst/prog2/main.c
new file mode 100644 (file)
index 0000000..76485e2
--- /dev/null
@@ -0,0 +1,25 @@
+/*     $OpenBSD: main.c,v 1.1 2023/04/09 23:41:48 gnezdo Exp $ */
+
+/*
+ * Copyright (c) 2013 Kurt Miller <kurt@intricatesoftware.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "aa.h"
+
+int
+main()
+{
+       return (aa());
+}