• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2017 FUJITSU LIMITED. All rights reserved.
4  * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
5  */
6 
7 /*
8  * Test for EFAULT when rlim points outside the accessible address space.
9  */
10 
11 #define _GNU_SOURCE
12 #include <errno.h>
13 #include <sys/resource.h>
14 #include <sys/time.h>
15 #include <sys/wait.h>
16 #include <stdlib.h>
17 
18 #include "tst_test.h"
19 
20 static void *bad_addr;
21 
verify_setrlimit(void)22 static void verify_setrlimit(void)
23 {
24 	int status;
25 	pid_t pid;
26 
27 	pid = SAFE_FORK();
28 	if (!pid) {
29 		TEST(setrlimit(RLIMIT_NOFILE, bad_addr));
30 		if (TST_RET != -1) {
31 			tst_res(TFAIL, "setrlimit()  succeeded unexpectedly");
32 			exit(0);
33 		}
34 
35 		/* Usually, setrlimit() should return EFAULT */
36 		if (TST_ERR == EFAULT) {
37 			tst_res(TPASS | TTERRNO,
38 				"setrlimit() failed as expected");
39 		} else {
40 			tst_res(TFAIL | TTERRNO,
41 				"setrlimit() should fail with EFAULT, got");
42 		}
43 
44 		exit(0);
45 	}
46 
47 	SAFE_WAITPID(pid, &status, 0);
48 
49 	/* If glibc has to convert between 32bit and 64bit struct rlimit
50 	 * in some cases, it is possible to get SegFault.
51 	 */
52 	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV) {
53 		tst_res(TPASS, "setrlimit() caused SIGSEGV");
54 		return;
55 	}
56 
57 	if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
58 		return;
59 
60 	tst_res(TFAIL, "child %s", tst_strstatus(status));
61 }
62 
setup(void)63 static void setup(void)
64 {
65 	bad_addr = tst_get_bad_addr(NULL);
66 }
67 
68 static struct tst_test test = {
69 	.test_all = verify_setrlimit,
70 	.forks_child = 1,
71 	.setup = setup,
72 };
73