xref: /aosp_15_r20/external/ltp/testcases/kernel/security/aslr/aslr01.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (C) 2024 SUSE LLC <[email protected]>
4*49cdfc7eSAndroid Build Coastguard Worker  */
5*49cdfc7eSAndroid Build Coastguard Worker 
6*49cdfc7eSAndroid Build Coastguard Worker /*\
7*49cdfc7eSAndroid Build Coastguard Worker  * [Description]
8*49cdfc7eSAndroid Build Coastguard Worker  *
9*49cdfc7eSAndroid Build Coastguard Worker  * Test that address space layout randomization (ASLR) is sufficiently random.
10*49cdfc7eSAndroid Build Coastguard Worker  * A bug in dynamic library mmapping may reduce ASLR randomness if the library
11*49cdfc7eSAndroid Build Coastguard Worker  * file is larger than hugepage size. In 32bit compat mode, this may
12*49cdfc7eSAndroid Build Coastguard Worker  * completely disable ASLR and force large dynamic libraries to be loaded
13*49cdfc7eSAndroid Build Coastguard Worker  * at fixed addresses.
14*49cdfc7eSAndroid Build Coastguard Worker  *
15*49cdfc7eSAndroid Build Coastguard Worker  * The issue may not be reproducible if hugepage support is missing or no
16*49cdfc7eSAndroid Build Coastguard Worker  * sufficiently large library is loaded into the test program. If libc is not
17*49cdfc7eSAndroid Build Coastguard Worker  * large enough, you may use `export LD_PRELOAD=...` to load another
18*49cdfc7eSAndroid Build Coastguard Worker  * sufficiently large library. The export keyword is required because
19*49cdfc7eSAndroid Build Coastguard Worker  * the checks are done on a subprocess.
20*49cdfc7eSAndroid Build Coastguard Worker  *
21*49cdfc7eSAndroid Build Coastguard Worker  * In normal mode, the test checks that library base address has a minimum
22*49cdfc7eSAndroid Build Coastguard Worker  * number of random bits (configurable using the -b option). In strict mode,
23*49cdfc7eSAndroid Build Coastguard Worker  * the test checks that library base address is aligned to regular pagesize
24*49cdfc7eSAndroid Build Coastguard Worker  * (not hugepage) and the number of random bits is at least
25*49cdfc7eSAndroid Build Coastguard Worker  * CONFIG_ARCH_MMAP_RND_BITS_MIN or the compat equivalent. The -b option is
26*49cdfc7eSAndroid Build Coastguard Worker  * ignored.
27*49cdfc7eSAndroid Build Coastguard Worker  */
28*49cdfc7eSAndroid Build Coastguard Worker 
29*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
30*49cdfc7eSAndroid Build Coastguard Worker #include <string.h>
31*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
32*49cdfc7eSAndroid Build Coastguard Worker #include <inttypes.h>
33*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
34*49cdfc7eSAndroid Build Coastguard Worker 
35*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
36*49cdfc7eSAndroid Build Coastguard Worker #include "tst_kernel.h"
37*49cdfc7eSAndroid Build Coastguard Worker #include "tst_kconfig.h"
38*49cdfc7eSAndroid Build Coastguard Worker #include "tst_safe_stdio.h"
39*49cdfc7eSAndroid Build Coastguard Worker 
40*49cdfc7eSAndroid Build Coastguard Worker /* Indices for aslr_kconfigs[] below */
41*49cdfc7eSAndroid Build Coastguard Worker #define ASLR_HAVE_COMPAT 0
42*49cdfc7eSAndroid Build Coastguard Worker #define ASLR_MINBITS 1
43*49cdfc7eSAndroid Build Coastguard Worker #define ASLR_COMPAT_MINBITS 2
44*49cdfc7eSAndroid Build Coastguard Worker 
45*49cdfc7eSAndroid Build Coastguard Worker static int pagebits, minbits = 8;
46*49cdfc7eSAndroid Build Coastguard Worker static char *minbits_str, *strict_check;
47*49cdfc7eSAndroid Build Coastguard Worker static char lib_path[PATH_MAX];
48*49cdfc7eSAndroid Build Coastguard Worker static FILE *ldd;
49*49cdfc7eSAndroid Build Coastguard Worker 
50*49cdfc7eSAndroid Build Coastguard Worker static struct tst_kconfig_var aslr_kconfigs[] = {
51*49cdfc7eSAndroid Build Coastguard Worker 	TST_KCONFIG_INIT("CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS"),
52*49cdfc7eSAndroid Build Coastguard Worker 	TST_KCONFIG_INIT("CONFIG_ARCH_MMAP_RND_BITS_MIN"),
53*49cdfc7eSAndroid Build Coastguard Worker 	TST_KCONFIG_INIT("CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN"),
54*49cdfc7eSAndroid Build Coastguard Worker };
55*49cdfc7eSAndroid Build Coastguard Worker 
count_align_bits(size_t val)56*49cdfc7eSAndroid Build Coastguard Worker static int count_align_bits(size_t val)
57*49cdfc7eSAndroid Build Coastguard Worker {
58*49cdfc7eSAndroid Build Coastguard Worker 	int ret = 0;
59*49cdfc7eSAndroid Build Coastguard Worker 
60*49cdfc7eSAndroid Build Coastguard Worker 	for (; val && !(val & 0x1); val >>= 1, ret++)
61*49cdfc7eSAndroid Build Coastguard Worker 		;
62*49cdfc7eSAndroid Build Coastguard Worker 
63*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
64*49cdfc7eSAndroid Build Coastguard Worker }
65*49cdfc7eSAndroid Build Coastguard Worker 
count_bits(size_t val)66*49cdfc7eSAndroid Build Coastguard Worker static int count_bits(size_t val)
67*49cdfc7eSAndroid Build Coastguard Worker {
68*49cdfc7eSAndroid Build Coastguard Worker 	int ret = 0;
69*49cdfc7eSAndroid Build Coastguard Worker 
70*49cdfc7eSAndroid Build Coastguard Worker 	for (; val; val >>= 1) {
71*49cdfc7eSAndroid Build Coastguard Worker 		if (val & 1)
72*49cdfc7eSAndroid Build Coastguard Worker 			ret++;
73*49cdfc7eSAndroid Build Coastguard Worker 	}
74*49cdfc7eSAndroid Build Coastguard Worker 
75*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
76*49cdfc7eSAndroid Build Coastguard Worker }
77*49cdfc7eSAndroid Build Coastguard Worker 
78*49cdfc7eSAndroid Build Coastguard Worker /* Extract library path and base address from a line of ldd output. */
parse_mapping(const char * line,char * path,uint64_t * addr)79*49cdfc7eSAndroid Build Coastguard Worker static int parse_mapping(const char *line, char *path, uint64_t *addr)
80*49cdfc7eSAndroid Build Coastguard Worker {
81*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
82*49cdfc7eSAndroid Build Coastguard Worker 
83*49cdfc7eSAndroid Build Coastguard Worker 	line = strchr(line, '/');
84*49cdfc7eSAndroid Build Coastguard Worker 
85*49cdfc7eSAndroid Build Coastguard Worker 	if (!line)
86*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
87*49cdfc7eSAndroid Build Coastguard Worker 
88*49cdfc7eSAndroid Build Coastguard Worker 	ret = sscanf(line, "%s (0x%" PRIx64 ")", path, addr);
89*49cdfc7eSAndroid Build Coastguard Worker 	return ret >= 2;
90*49cdfc7eSAndroid Build Coastguard Worker }
91*49cdfc7eSAndroid Build Coastguard Worker 
92*49cdfc7eSAndroid Build Coastguard Worker /*
93*49cdfc7eSAndroid Build Coastguard Worker  * Run ldd on the test executable and pass each library/address to callback.
94*49cdfc7eSAndroid Build Coastguard Worker  * If the callback returns non-zero, the reader loop will immediately exit.
95*49cdfc7eSAndroid Build Coastguard Worker  */
read_shared_libraries(int (* callback)(void *,const char *,uint64_t),void * arg)96*49cdfc7eSAndroid Build Coastguard Worker static void read_shared_libraries(int (*callback)(void*, const char*, uint64_t),
97*49cdfc7eSAndroid Build Coastguard Worker 	void *arg)
98*49cdfc7eSAndroid Build Coastguard Worker {
99*49cdfc7eSAndroid Build Coastguard Worker 	char line[PATH_MAX], path[PATH_MAX];
100*49cdfc7eSAndroid Build Coastguard Worker 	uint64_t addr;
101*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
102*49cdfc7eSAndroid Build Coastguard Worker 
103*49cdfc7eSAndroid Build Coastguard Worker 	sprintf(path, "ldd /proc/%d/exe", getpid());
104*49cdfc7eSAndroid Build Coastguard Worker 	ldd = SAFE_POPEN(path, "r");
105*49cdfc7eSAndroid Build Coastguard Worker 
106*49cdfc7eSAndroid Build Coastguard Worker 	while (fgets(line, PATH_MAX, ldd)) {
107*49cdfc7eSAndroid Build Coastguard Worker 		if (*line && !feof(ldd) && line[strlen(line) - 1] != '\n')
108*49cdfc7eSAndroid Build Coastguard Worker 			tst_brk(TBROK, "Dynamic library entry too long");
109*49cdfc7eSAndroid Build Coastguard Worker 
110*49cdfc7eSAndroid Build Coastguard Worker 		if (!parse_mapping(line, path, &addr))
111*49cdfc7eSAndroid Build Coastguard Worker 			continue;
112*49cdfc7eSAndroid Build Coastguard Worker 
113*49cdfc7eSAndroid Build Coastguard Worker 		if (callback(arg, path, addr))
114*49cdfc7eSAndroid Build Coastguard Worker 			break;
115*49cdfc7eSAndroid Build Coastguard Worker 	}
116*49cdfc7eSAndroid Build Coastguard Worker 
117*49cdfc7eSAndroid Build Coastguard Worker 	while (fgets(line, PATH_MAX, ldd))
118*49cdfc7eSAndroid Build Coastguard Worker 		;
119*49cdfc7eSAndroid Build Coastguard Worker 
120*49cdfc7eSAndroid Build Coastguard Worker 	ret = pclose(ldd);
121*49cdfc7eSAndroid Build Coastguard Worker 	ldd = NULL;
122*49cdfc7eSAndroid Build Coastguard Worker 
123*49cdfc7eSAndroid Build Coastguard Worker 	if (!WIFEXITED(ret) || WEXITSTATUS(ret))
124*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK, "Reading dynamic libraries failed");
125*49cdfc7eSAndroid Build Coastguard Worker }
126*49cdfc7eSAndroid Build Coastguard Worker 
find_large_lib_callback(void * arg,const char * path,uint64_t addr LTP_ATTRIBUTE_UNUSED)127*49cdfc7eSAndroid Build Coastguard Worker static int find_large_lib_callback(void *arg, const char *path,
128*49cdfc7eSAndroid Build Coastguard Worker 	uint64_t addr LTP_ATTRIBUTE_UNUSED)
129*49cdfc7eSAndroid Build Coastguard Worker {
130*49cdfc7eSAndroid Build Coastguard Worker 	size_t *libsize = arg;
131*49cdfc7eSAndroid Build Coastguard Worker 	struct stat statbuf;
132*49cdfc7eSAndroid Build Coastguard Worker 
133*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_STAT(path, &statbuf);
134*49cdfc7eSAndroid Build Coastguard Worker 
135*49cdfc7eSAndroid Build Coastguard Worker 	if (*libsize < (size_t)statbuf.st_size) {
136*49cdfc7eSAndroid Build Coastguard Worker 		strcpy(lib_path, path);
137*49cdfc7eSAndroid Build Coastguard Worker 		*libsize = statbuf.st_size;
138*49cdfc7eSAndroid Build Coastguard Worker 	}
139*49cdfc7eSAndroid Build Coastguard Worker 
140*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
141*49cdfc7eSAndroid Build Coastguard Worker }
142*49cdfc7eSAndroid Build Coastguard Worker 
find_large_lib(void)143*49cdfc7eSAndroid Build Coastguard Worker static void find_large_lib(void)
144*49cdfc7eSAndroid Build Coastguard Worker {
145*49cdfc7eSAndroid Build Coastguard Worker 	size_t hpsize, libsize = 0;
146*49cdfc7eSAndroid Build Coastguard Worker 
147*49cdfc7eSAndroid Build Coastguard Worker 	read_shared_libraries(find_large_lib_callback, &libsize);
148*49cdfc7eSAndroid Build Coastguard Worker 
149*49cdfc7eSAndroid Build Coastguard Worker 	if (!libsize) {
150*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TCONF,
151*49cdfc7eSAndroid Build Coastguard Worker 			"No dynamic libraries loaded, please use LD_PRELOAD");
152*49cdfc7eSAndroid Build Coastguard Worker 	}
153*49cdfc7eSAndroid Build Coastguard Worker 
154*49cdfc7eSAndroid Build Coastguard Worker 	hpsize = tst_get_hugepage_size();
155*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TINFO, "Largest loaded library: %s (%zu bytes)", lib_path,
156*49cdfc7eSAndroid Build Coastguard Worker 		libsize);
157*49cdfc7eSAndroid Build Coastguard Worker 
158*49cdfc7eSAndroid Build Coastguard Worker 	if (!hpsize) {
159*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TCONF, "Hugepage support appears to be missing");
160*49cdfc7eSAndroid Build Coastguard Worker 	} else if (libsize < hpsize) {
161*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TCONF, "The largest dynamic library is smaller than hugepage size, "
162*49cdfc7eSAndroid Build Coastguard Worker 				"please use LD_PRELOAD to add larger library");
163*49cdfc7eSAndroid Build Coastguard Worker 	}
164*49cdfc7eSAndroid Build Coastguard Worker }
165*49cdfc7eSAndroid Build Coastguard Worker 
get_lib_address_callback(void * arg,const char * path,uint64_t addr)166*49cdfc7eSAndroid Build Coastguard Worker static int get_lib_address_callback(void *arg, const char *path, uint64_t addr)
167*49cdfc7eSAndroid Build Coastguard Worker {
168*49cdfc7eSAndroid Build Coastguard Worker 	uint64_t *out_addr = arg;
169*49cdfc7eSAndroid Build Coastguard Worker 
170*49cdfc7eSAndroid Build Coastguard Worker 	if (!strcmp(path, lib_path)) {
171*49cdfc7eSAndroid Build Coastguard Worker 		*out_addr = addr;
172*49cdfc7eSAndroid Build Coastguard Worker 		return 1;
173*49cdfc7eSAndroid Build Coastguard Worker 	}
174*49cdfc7eSAndroid Build Coastguard Worker 
175*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
176*49cdfc7eSAndroid Build Coastguard Worker }
177*49cdfc7eSAndroid Build Coastguard Worker 
setup(void)178*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
179*49cdfc7eSAndroid Build Coastguard Worker {
180*49cdfc7eSAndroid Build Coastguard Worker 	int compat = tst_is_compat_mode();
181*49cdfc7eSAndroid Build Coastguard Worker 	const char *kconf_minbits, *minbits_path;
182*49cdfc7eSAndroid Build Coastguard Worker 
183*49cdfc7eSAndroid Build Coastguard Worker 	pagebits = count_align_bits(getpagesize());
184*49cdfc7eSAndroid Build Coastguard Worker 	tst_kconfig_read(aslr_kconfigs, ARRAY_SIZE(aslr_kconfigs));
185*49cdfc7eSAndroid Build Coastguard Worker 
186*49cdfc7eSAndroid Build Coastguard Worker 	if (compat && aslr_kconfigs[ASLR_HAVE_COMPAT].choice != 'y')
187*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TCONF, "ASLR not supported in compat mode");
188*49cdfc7eSAndroid Build Coastguard Worker 
189*49cdfc7eSAndroid Build Coastguard Worker 	if (!strict_check && tst_parse_int(minbits_str, &minbits, 1, 64))
190*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK, "Invalid bit count argument '%s'", minbits_str);
191*49cdfc7eSAndroid Build Coastguard Worker 
192*49cdfc7eSAndroid Build Coastguard Worker 	if (strict_check) {
193*49cdfc7eSAndroid Build Coastguard Worker 		if (compat) {
194*49cdfc7eSAndroid Build Coastguard Worker 			kconf_minbits = aslr_kconfigs[ASLR_COMPAT_MINBITS].val;
195*49cdfc7eSAndroid Build Coastguard Worker 			minbits_path = "/proc/sys/vm/mmap_rnd_compat_bits";
196*49cdfc7eSAndroid Build Coastguard Worker 		} else {
197*49cdfc7eSAndroid Build Coastguard Worker 			kconf_minbits = aslr_kconfigs[ASLR_MINBITS].val;
198*49cdfc7eSAndroid Build Coastguard Worker 			minbits_path = "/proc/sys/vm/mmap_rnd_bits";
199*49cdfc7eSAndroid Build Coastguard Worker 		}
200*49cdfc7eSAndroid Build Coastguard Worker 
201*49cdfc7eSAndroid Build Coastguard Worker 		/*
202*49cdfc7eSAndroid Build Coastguard Worker 		 * Reading mmap_rnd_bits usually requires root privileges.
203*49cdfc7eSAndroid Build Coastguard Worker 		 * Fall back to kernel config values if unprivileged.
204*49cdfc7eSAndroid Build Coastguard Worker 		 */
205*49cdfc7eSAndroid Build Coastguard Worker 		if (!access(minbits_path, R_OK))
206*49cdfc7eSAndroid Build Coastguard Worker 			SAFE_FILE_SCANF(minbits_path, "%d", &minbits);
207*49cdfc7eSAndroid Build Coastguard Worker 		else if (!kconf_minbits)
208*49cdfc7eSAndroid Build Coastguard Worker 			tst_brk(TBROK, "Cannot determine kernel ASLR min bits");
209*49cdfc7eSAndroid Build Coastguard Worker 		else if (tst_parse_int(kconf_minbits, &minbits, 1, 64))
210*49cdfc7eSAndroid Build Coastguard Worker 			tst_brk(TBROK, "Invalid kernel ASLR min bits value");
211*49cdfc7eSAndroid Build Coastguard Worker 	}
212*49cdfc7eSAndroid Build Coastguard Worker 
213*49cdfc7eSAndroid Build Coastguard Worker 	find_large_lib();
214*49cdfc7eSAndroid Build Coastguard Worker }
215*49cdfc7eSAndroid Build Coastguard Worker 
run(void)216*49cdfc7eSAndroid Build Coastguard Worker static void run(void)
217*49cdfc7eSAndroid Build Coastguard Worker {
218*49cdfc7eSAndroid Build Coastguard Worker 	uint64_t rndbits = 0, fixbits, addr;
219*49cdfc7eSAndroid Build Coastguard Worker 	int rndcount, aligncount, i;
220*49cdfc7eSAndroid Build Coastguard Worker 
221*49cdfc7eSAndroid Build Coastguard Worker 	fixbits = ~rndbits;
222*49cdfc7eSAndroid Build Coastguard Worker 
223*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < 512; i++) {
224*49cdfc7eSAndroid Build Coastguard Worker 		addr = 0;
225*49cdfc7eSAndroid Build Coastguard Worker 		read_shared_libraries(get_lib_address_callback, &addr);
226*49cdfc7eSAndroid Build Coastguard Worker 
227*49cdfc7eSAndroid Build Coastguard Worker 		if (!addr) {
228*49cdfc7eSAndroid Build Coastguard Worker 			tst_res(TWARN, "Library %s not found?!", lib_path);
229*49cdfc7eSAndroid Build Coastguard Worker 			continue;
230*49cdfc7eSAndroid Build Coastguard Worker 		}
231*49cdfc7eSAndroid Build Coastguard Worker 
232*49cdfc7eSAndroid Build Coastguard Worker 		rndbits |= addr;
233*49cdfc7eSAndroid Build Coastguard Worker 		fixbits &= addr;
234*49cdfc7eSAndroid Build Coastguard Worker 	}
235*49cdfc7eSAndroid Build Coastguard Worker 
236*49cdfc7eSAndroid Build Coastguard Worker 	rndcount = count_bits(rndbits & ~fixbits);
237*49cdfc7eSAndroid Build Coastguard Worker 	aligncount = count_align_bits(rndbits);
238*49cdfc7eSAndroid Build Coastguard Worker 
239*49cdfc7eSAndroid Build Coastguard Worker 	if (rndcount < minbits) {
240*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TFAIL,
241*49cdfc7eSAndroid Build Coastguard Worker 			"Large lib base address has less than %d random bits",
242*49cdfc7eSAndroid Build Coastguard Worker 			minbits);
243*49cdfc7eSAndroid Build Coastguard Worker 		return;
244*49cdfc7eSAndroid Build Coastguard Worker 	}
245*49cdfc7eSAndroid Build Coastguard Worker 
246*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TPASS, "Library address has %d random bits", rndcount);
247*49cdfc7eSAndroid Build Coastguard Worker 	tst_res(TINFO, "Library base address alignment: %d bits", aligncount);
248*49cdfc7eSAndroid Build Coastguard Worker 
249*49cdfc7eSAndroid Build Coastguard Worker 	if (aligncount > pagebits) {
250*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(strict_check ? TFAIL : TINFO,
251*49cdfc7eSAndroid Build Coastguard Worker 			"Base address alignment is higher than expected (%d)",
252*49cdfc7eSAndroid Build Coastguard Worker 			pagebits);
253*49cdfc7eSAndroid Build Coastguard Worker 	}
254*49cdfc7eSAndroid Build Coastguard Worker }
255*49cdfc7eSAndroid Build Coastguard Worker 
cleanup(void)256*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
257*49cdfc7eSAndroid Build Coastguard Worker {
258*49cdfc7eSAndroid Build Coastguard Worker 	if (ldd) {
259*49cdfc7eSAndroid Build Coastguard Worker 		char buf[PATH_MAX];
260*49cdfc7eSAndroid Build Coastguard Worker 
261*49cdfc7eSAndroid Build Coastguard Worker 		while (fgets(buf, PATH_MAX, ldd))
262*49cdfc7eSAndroid Build Coastguard Worker 			;
263*49cdfc7eSAndroid Build Coastguard Worker 
264*49cdfc7eSAndroid Build Coastguard Worker 		pclose(ldd);
265*49cdfc7eSAndroid Build Coastguard Worker 	}
266*49cdfc7eSAndroid Build Coastguard Worker }
267*49cdfc7eSAndroid Build Coastguard Worker 
268*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
269*49cdfc7eSAndroid Build Coastguard Worker 	.test_all = run,
270*49cdfc7eSAndroid Build Coastguard Worker 	.setup = setup,
271*49cdfc7eSAndroid Build Coastguard Worker 	.cleanup = cleanup,
272*49cdfc7eSAndroid Build Coastguard Worker 	.forks_child = 1,
273*49cdfc7eSAndroid Build Coastguard Worker 	.options = (struct tst_option []) {
274*49cdfc7eSAndroid Build Coastguard Worker 		{"b:", &minbits_str, "Minimum ASLR random bits (default: 8)"},
275*49cdfc7eSAndroid Build Coastguard Worker 		{"s", &strict_check, "Run in strict mode"},
276*49cdfc7eSAndroid Build Coastguard Worker 		{}
277*49cdfc7eSAndroid Build Coastguard Worker 	},
278*49cdfc7eSAndroid Build Coastguard Worker 	.needs_kconfigs = (const char *[]) {
279*49cdfc7eSAndroid Build Coastguard Worker 		"CONFIG_HAVE_ARCH_MMAP_RND_BITS=y",
280*49cdfc7eSAndroid Build Coastguard Worker 		NULL
281*49cdfc7eSAndroid Build Coastguard Worker 	},
282*49cdfc7eSAndroid Build Coastguard Worker 	.needs_cmds = (const char *[]) {
283*49cdfc7eSAndroid Build Coastguard Worker 		"ldd",
284*49cdfc7eSAndroid Build Coastguard Worker 		NULL
285*49cdfc7eSAndroid Build Coastguard Worker 	},
286*49cdfc7eSAndroid Build Coastguard Worker };
287