xref: /freebsd/libexec/rtld-elf/tests/ld_library_pathfds.c (revision 6b22f423cfa76dc95ed00e5a8f43e563cc34b9a6)
1*6b22f423SJonathan Anderson /*-
2*6b22f423SJonathan Anderson  * Copyright 2014 Jonathan Anderson.
3*6b22f423SJonathan Anderson  * All rights reserved.
4*6b22f423SJonathan Anderson  *
5*6b22f423SJonathan Anderson  * Redistribution and use in source and binary forms, with or without
6*6b22f423SJonathan Anderson  * modification, are permitted provided that the following conditions
7*6b22f423SJonathan Anderson  * are met:
8*6b22f423SJonathan Anderson  * 1. Redistributions of source code must retain the above copyright
9*6b22f423SJonathan Anderson  *    notice, this list of conditions and the following disclaimer.
10*6b22f423SJonathan Anderson  * 2. Redistributions in binary form must reproduce the above copyright
11*6b22f423SJonathan Anderson  *    notice, this list of conditions and the following disclaimer in the
12*6b22f423SJonathan Anderson  *    documentation and/or other materials provided with the distribution.
13*6b22f423SJonathan Anderson  *
14*6b22f423SJonathan Anderson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15*6b22f423SJonathan Anderson  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16*6b22f423SJonathan Anderson  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17*6b22f423SJonathan Anderson  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18*6b22f423SJonathan Anderson  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19*6b22f423SJonathan Anderson  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20*6b22f423SJonathan Anderson  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21*6b22f423SJonathan Anderson  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22*6b22f423SJonathan Anderson  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23*6b22f423SJonathan Anderson  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24*6b22f423SJonathan Anderson  *
25*6b22f423SJonathan Anderson  * $FreeBSD$
26*6b22f423SJonathan Anderson  */
27*6b22f423SJonathan Anderson 
28*6b22f423SJonathan Anderson #include <atf-c.h>
29*6b22f423SJonathan Anderson #include <fcntl.h>
30*6b22f423SJonathan Anderson #include <stdio.h>
31*6b22f423SJonathan Anderson 
32*6b22f423SJonathan Anderson 
33*6b22f423SJonathan Anderson struct descriptors {
34*6b22f423SJonathan Anderson 	int	binary;
35*6b22f423SJonathan Anderson 	int	testdir;
36*6b22f423SJonathan Anderson 	int	root;
37*6b22f423SJonathan Anderson 	int	etc;
38*6b22f423SJonathan Anderson 	int	usr;
39*6b22f423SJonathan Anderson };
40*6b22f423SJonathan Anderson 
41*6b22f423SJonathan Anderson static void	setup(struct descriptors *);
42*6b22f423SJonathan Anderson static void	expect_success(int binary, char *pathfds);
43*6b22f423SJonathan Anderson static void	expect_missing_library(int binary, char *pathfds);
44*6b22f423SJonathan Anderson 
45*6b22f423SJonathan Anderson static void	try_to_run(int binary, int expected_exit_status,
46*6b22f423SJonathan Anderson     char * const *env, const char *expected_out, const char *expected_err);
47*6b22f423SJonathan Anderson static int	opendir(const char *name);
48*6b22f423SJonathan Anderson static int	opendirat(int parent, const char *name);
49*6b22f423SJonathan Anderson 
50*6b22f423SJonathan Anderson 
51*6b22f423SJonathan Anderson ATF_TC_WITHOUT_HEAD(missing_library);
52*6b22f423SJonathan Anderson ATF_TC_BODY(missing_library, tc)
53*6b22f423SJonathan Anderson {
54*6b22f423SJonathan Anderson 	struct descriptors files;
55*6b22f423SJonathan Anderson 
56*6b22f423SJonathan Anderson 	setup(&files);
57*6b22f423SJonathan Anderson 	expect_missing_library(files.binary, NULL);
58*6b22f423SJonathan Anderson }
59*6b22f423SJonathan Anderson 
60*6b22f423SJonathan Anderson 
61*6b22f423SJonathan Anderson ATF_TC_WITHOUT_HEAD(wrong_library_directories);
62*6b22f423SJonathan Anderson ATF_TC_BODY(wrong_library_directories, tc)
63*6b22f423SJonathan Anderson {
64*6b22f423SJonathan Anderson 	struct descriptors files;
65*6b22f423SJonathan Anderson 	char *pathfds;
66*6b22f423SJonathan Anderson 
67*6b22f423SJonathan Anderson 	setup(&files);
68*6b22f423SJonathan Anderson 	ATF_REQUIRE(
69*6b22f423SJonathan Anderson 		asprintf(&pathfds, "LD_LIBRARY_PATH_FDS=%d", files.etc) > 0);
70*6b22f423SJonathan Anderson 
71*6b22f423SJonathan Anderson 	expect_missing_library(files.binary, pathfds);
72*6b22f423SJonathan Anderson }
73*6b22f423SJonathan Anderson 
74*6b22f423SJonathan Anderson 
75*6b22f423SJonathan Anderson ATF_TC_WITHOUT_HEAD(bad_library_directories);
76*6b22f423SJonathan Anderson ATF_TC_BODY(bad_library_directories, tc)
77*6b22f423SJonathan Anderson {
78*6b22f423SJonathan Anderson 	struct descriptors files;
79*6b22f423SJonathan Anderson 	char *pathfds;
80*6b22f423SJonathan Anderson 
81*6b22f423SJonathan Anderson 	setup(&files);
82*6b22f423SJonathan Anderson 	ATF_REQUIRE(asprintf(&pathfds, "::", files.etc) > 0);
83*6b22f423SJonathan Anderson 
84*6b22f423SJonathan Anderson 	expect_missing_library(files.binary, pathfds);
85*6b22f423SJonathan Anderson }
86*6b22f423SJonathan Anderson 
87*6b22f423SJonathan Anderson 
88*6b22f423SJonathan Anderson ATF_TC_WITHOUT_HEAD(single_library_directory);
89*6b22f423SJonathan Anderson ATF_TC_BODY(single_library_directory, tc)
90*6b22f423SJonathan Anderson {
91*6b22f423SJonathan Anderson 	struct descriptors files;
92*6b22f423SJonathan Anderson 	char *pathfds;
93*6b22f423SJonathan Anderson 
94*6b22f423SJonathan Anderson 	setup(&files);
95*6b22f423SJonathan Anderson 	ATF_REQUIRE(
96*6b22f423SJonathan Anderson 	    asprintf(&pathfds, "LD_LIBRARY_PATH_FDS=%d", files.testdir) > 0);
97*6b22f423SJonathan Anderson 
98*6b22f423SJonathan Anderson 	expect_success(files.binary, pathfds);
99*6b22f423SJonathan Anderson }
100*6b22f423SJonathan Anderson 
101*6b22f423SJonathan Anderson 
102*6b22f423SJonathan Anderson ATF_TC_WITHOUT_HEAD(first_library_directory);
103*6b22f423SJonathan Anderson ATF_TC_BODY(first_library_directory, tc)
104*6b22f423SJonathan Anderson {
105*6b22f423SJonathan Anderson 	struct descriptors files;
106*6b22f423SJonathan Anderson 	char *pathfds;
107*6b22f423SJonathan Anderson 
108*6b22f423SJonathan Anderson 	setup(&files);
109*6b22f423SJonathan Anderson 	ATF_REQUIRE(
110*6b22f423SJonathan Anderson 	    asprintf(&pathfds, "LD_LIBRARY_PATH_FDS=%d:%d",
111*6b22f423SJonathan Anderson 		files.testdir, files.etc) > 0);
112*6b22f423SJonathan Anderson 
113*6b22f423SJonathan Anderson 	expect_success(files.binary, pathfds);
114*6b22f423SJonathan Anderson }
115*6b22f423SJonathan Anderson 
116*6b22f423SJonathan Anderson 
117*6b22f423SJonathan Anderson ATF_TC_WITHOUT_HEAD(middle_library_directory);
118*6b22f423SJonathan Anderson ATF_TC_BODY(middle_library_directory, tc)
119*6b22f423SJonathan Anderson {
120*6b22f423SJonathan Anderson 	struct descriptors files;
121*6b22f423SJonathan Anderson 	char *pathfds;
122*6b22f423SJonathan Anderson 
123*6b22f423SJonathan Anderson 	setup(&files);
124*6b22f423SJonathan Anderson 	ATF_REQUIRE(
125*6b22f423SJonathan Anderson 	    asprintf(&pathfds, "LD_LIBRARY_PATH_FDS=%d:%d:%d",
126*6b22f423SJonathan Anderson 		files.root, files.testdir, files.usr) > 0);
127*6b22f423SJonathan Anderson 
128*6b22f423SJonathan Anderson 	expect_success(files.binary, pathfds);
129*6b22f423SJonathan Anderson }
130*6b22f423SJonathan Anderson 
131*6b22f423SJonathan Anderson 
132*6b22f423SJonathan Anderson ATF_TC_WITHOUT_HEAD(last_library_directory);
133*6b22f423SJonathan Anderson ATF_TC_BODY(last_library_directory, tc)
134*6b22f423SJonathan Anderson {
135*6b22f423SJonathan Anderson 	struct descriptors files;
136*6b22f423SJonathan Anderson 	char *pathfds;
137*6b22f423SJonathan Anderson 
138*6b22f423SJonathan Anderson 	setup(&files);
139*6b22f423SJonathan Anderson 	ATF_REQUIRE(
140*6b22f423SJonathan Anderson 	    asprintf(&pathfds, "LD_LIBRARY_PATH_FDS=%d:%d",
141*6b22f423SJonathan Anderson 		files.root, files.testdir) > 0);
142*6b22f423SJonathan Anderson 
143*6b22f423SJonathan Anderson 	expect_success(files.binary, pathfds);
144*6b22f423SJonathan Anderson }
145*6b22f423SJonathan Anderson 
146*6b22f423SJonathan Anderson 
147*6b22f423SJonathan Anderson 
148*6b22f423SJonathan Anderson /* Register test cases with ATF. */
149*6b22f423SJonathan Anderson ATF_TP_ADD_TCS(tp)
150*6b22f423SJonathan Anderson {
151*6b22f423SJonathan Anderson 	ATF_TP_ADD_TC(tp, missing_library);
152*6b22f423SJonathan Anderson 	ATF_TP_ADD_TC(tp, wrong_library_directories);
153*6b22f423SJonathan Anderson 	ATF_TP_ADD_TC(tp, bad_library_directories);
154*6b22f423SJonathan Anderson 	ATF_TP_ADD_TC(tp, single_library_directory);
155*6b22f423SJonathan Anderson 	ATF_TP_ADD_TC(tp, first_library_directory);
156*6b22f423SJonathan Anderson 	ATF_TP_ADD_TC(tp, middle_library_directory);
157*6b22f423SJonathan Anderson 	ATF_TP_ADD_TC(tp, last_library_directory);
158*6b22f423SJonathan Anderson 
159*6b22f423SJonathan Anderson 	return atf_no_error();
160*6b22f423SJonathan Anderson }
161*6b22f423SJonathan Anderson 
162*6b22f423SJonathan Anderson 
163*6b22f423SJonathan Anderson static void
164*6b22f423SJonathan Anderson setup(struct descriptors *dp)
165*6b22f423SJonathan Anderson {
166*6b22f423SJonathan Anderson 
167*6b22f423SJonathan Anderson 	ATF_REQUIRE((dp->testdir = opendir(TESTSDIR)) >= 0);
168*6b22f423SJonathan Anderson 	ATF_REQUIRE(
169*6b22f423SJonathan Anderson 	    (dp->binary = openat(dp->testdir, "target", O_RDONLY)) >= 0);
170*6b22f423SJonathan Anderson 
171*6b22f423SJonathan Anderson 	ATF_REQUIRE((dp->root = opendir("/")) >= 0);
172*6b22f423SJonathan Anderson 	ATF_REQUIRE((dp->etc = opendirat(dp->root, "etc")) >= 0);
173*6b22f423SJonathan Anderson 	ATF_REQUIRE((dp->usr = opendirat(dp->root, "usr")) >= 0);
174*6b22f423SJonathan Anderson }
175*6b22f423SJonathan Anderson 
176*6b22f423SJonathan Anderson static void
177*6b22f423SJonathan Anderson expect_success(int binary, char *pathfds)
178*6b22f423SJonathan Anderson {
179*6b22f423SJonathan Anderson 	char * const env[] = { pathfds, NULL };
180*6b22f423SJonathan Anderson 	try_to_run(binary, 0, env, "the hypotenuse of 3 and 4 is 5\n", "");
181*6b22f423SJonathan Anderson }
182*6b22f423SJonathan Anderson 
183*6b22f423SJonathan Anderson static void
184*6b22f423SJonathan Anderson expect_missing_library(int binary, char *pathfds)
185*6b22f423SJonathan Anderson {
186*6b22f423SJonathan Anderson 	char * const env[] = { pathfds, NULL };
187*6b22f423SJonathan Anderson 	try_to_run(binary, 1, env, "",
188*6b22f423SJonathan Anderson 	   "Shared object \"libpythagoras.so.0\" not found,"
189*6b22f423SJonathan Anderson 	    " required by \"target\"\n");
190*6b22f423SJonathan Anderson }
191*6b22f423SJonathan Anderson 
192*6b22f423SJonathan Anderson 
193*6b22f423SJonathan Anderson static void
194*6b22f423SJonathan Anderson try_to_run(int binary, int exit_status, char * const *env,
195*6b22f423SJonathan Anderson         const char *expected_out, const char *expected_err)
196*6b22f423SJonathan Anderson {
197*6b22f423SJonathan Anderson 	pid_t child = atf_utils_fork();
198*6b22f423SJonathan Anderson 
199*6b22f423SJonathan Anderson 	if (child == 0) {
200*6b22f423SJonathan Anderson 		char * const args[] = { "target", NULL };
201*6b22f423SJonathan Anderson 
202*6b22f423SJonathan Anderson 		fexecve(binary, args, env);
203*6b22f423SJonathan Anderson 		atf_tc_fail("fexecve() failed");
204*6b22f423SJonathan Anderson 	}
205*6b22f423SJonathan Anderson 
206*6b22f423SJonathan Anderson 	atf_utils_wait(child, exit_status, expected_out, expected_err);
207*6b22f423SJonathan Anderson }
208*6b22f423SJonathan Anderson 
209*6b22f423SJonathan Anderson 
210*6b22f423SJonathan Anderson static int
211*6b22f423SJonathan Anderson opendir(const char *name)
212*6b22f423SJonathan Anderson {
213*6b22f423SJonathan Anderson 	return open(name, O_RDONLY | O_DIRECTORY);
214*6b22f423SJonathan Anderson }
215*6b22f423SJonathan Anderson 
216*6b22f423SJonathan Anderson static int
217*6b22f423SJonathan Anderson opendirat(int parent, const char *name)
218*6b22f423SJonathan Anderson {
219*6b22f423SJonathan Anderson 	return openat(parent, name, O_RDONLY | O_DIRECTORY);
220*6b22f423SJonathan Anderson }
221