rtld: add a test for RTLD_DEEPBIND

This tests that with RTLD_DEEPBIND, symbols are looked up in all of the
object's needed objects before the global object.

PR:		275393
Reviewed by:	kib
Sponsored by:	NetApp, Inc.
Sponsored by:	Klara, Inc.
Differential Revision:	https://reviews.freebsd.org/D42843
This commit is contained in:
Kyle Evans 2023-11-30 19:26:09 -06:00
parent 82506f26c0
commit d9c543b6b0
11 changed files with 172 additions and 2 deletions

View file

@ -436,6 +436,8 @@
rc
..
rtld-elf
rtld_deepbind
..
..
tftpd
..

View file

@ -1,6 +1,9 @@
SUBDIR+= libpythagoras target
SUBDIR+= libpythagoras libdeep libval libval2 target
TESTS_SUBDIRS+= rtld_deepbind
SUBDIR_DEPEND_libdeep= libval2
SUBDIR_DEPEND_rtld_deepbind= libval
SUBDIR_DEPEND_target= libpythagoras
ATF_TESTS_C= ld_library_pathfds

View file

@ -0,0 +1,3 @@
PACKAGE?= tests
TESTSDIR?= ${TESTSBASE}/libexec/rtld-elf

View file

@ -0,0 +1,15 @@
SHLIB?= deep
SHLIB_MAJOR= 0
LIBDIR= ${TESTSBASE}/libexec/rtld-elf/rtld_deepbind
SHLIBDIR= ${TESTSBASE}/libexec/rtld-elf/rtld_deepbind
SRCS= libdeep.c
LIBVAL2= ${.OBJDIR}/../libval2
LDFLAGS+= -L${LIBVAL2} -Wl,-rpath,'$$ORIGIN'
DPADD+= -lval2
LDADD+= -lval2
.include <bsd.lib.mk>

View file

@ -0,0 +1,28 @@
/*-
*
* Copyright (C) 2023 NetApp, Inc.
*
* SPDX-License-Identifier: BSD-2-Clause
*
*/
#include <stdio.h>
int get_value(void);
int proxy_get_value(void);
void set_value(int);
void proxy_set_value(int);
int
proxy_get_value(void)
{
return (get_value());
}
void
proxy_set_value(int val)
{
return (set_value(val));
}

View file

@ -0,0 +1,10 @@
SHLIB?= val
SHLIB_MAJOR= 0
LIBDIR= ${TESTSBASE}/libexec/rtld-elf/rtld_deepbind
SHLIBDIR= ${TESTSBASE}/libexec/rtld-elf/rtld_deepbind
SRCS= libval.c
.include <bsd.lib.mk>

View file

@ -0,0 +1,26 @@
/*-
*
* Copyright (C) 2023 NetApp, Inc.
*
* SPDX-License-Identifier: BSD-2-Clause
*
*/
static int val;
int get_value(void);
void set_value(int);
int
get_value(void)
{
return (val);
}
void
set_value(int nval)
{
val = nval;
}

View file

@ -0,0 +1,8 @@
LIBVAL= ${.CURDIR}/../libval
# Just rebuild libval
.PATH: ${LIBVAL:tA}
SHLIB?= val2
.include "${LIBVAL}/Makefile"

View file

@ -0,0 +1,10 @@
TESTSDIR?= ${TESTSBASE}/libexec/rtld-elf/rtld_deepbind
ATF_TESTS_C= rtld_deepbind
LIBVAL= ${.OBJDIR}/../libval
LDFLAGS.rtld_deepbind+= -L${LIBVAL} -Wl,-rpath,'$$ORIGIN'
DPADD+= -lval
LDADD+= -lval
.include <bsd.test.mk>

View file

@ -0,0 +1,65 @@
/*-
*
* Copyright (C) 2023 NetApp, Inc.
*
* SPDX-License-Identifier: BSD-2-Clause
*
*/
#include <dlfcn.h>
#include <atf-c.h>
int get_value(void);
void set_value(int);
#define APP_VALUE 5
#define LIB_VALUE 20
ATF_TC_WITHOUT_HEAD(deepbind_simple);
ATF_TC_BODY(deepbind_simple, tc)
{
void *hdl;
void (*proxy_set_value)(int);
int (*proxy_get_value)(void);
int app_value, lib_value;
set_value(APP_VALUE);
/*
* libdeep has a dependency on libval2.so, which is a rebuild of
* libval.so that provides get_value() and set_value() for both us and
* the lib. The lib's get_value() and set_value() should bind to the
* versions in libval2 instead of libval with RTLD_DEEPBIND.
*/
hdl = dlopen("$ORIGIN/libdeep.so", RTLD_LAZY | RTLD_DEEPBIND);
ATF_REQUIRE(hdl != NULL);
proxy_set_value = dlsym(hdl, "proxy_set_value");
ATF_REQUIRE(proxy_set_value != NULL);
proxy_get_value = dlsym(hdl, "proxy_get_value");
ATF_REQUIRE(proxy_get_value != NULL);
(*proxy_set_value)(LIB_VALUE);
lib_value = (*proxy_get_value)();
app_value = get_value();
/*
* In the initial implementation or if libdeep.so is *not* linked
* against its own libval2, then these both return the later set
* LIB_VALUE (20) as they bind to the symbol provided by libval and
* use its .bss val.
*/
ATF_REQUIRE_INTEQ(lib_value, LIB_VALUE);
ATF_REQUIRE_INTEQ(app_value, APP_VALUE);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, deepbind_simple);
return atf_no_error();
}

View file

@ -2,7 +2,7 @@
.include <bsd.own.mk>
PROG= target
BINDIR= ${TESTSBASE}/libexec/rtld-elf
BINDIR= ${TESTSDIR}
WARNS?= 3
CFLAGS+= -I${.CURDIR}/../libpythagoras