• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017 FUJITSU LIMITED. All rights reserved.
3  * Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
4  *
5  * This program is free software;  you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  * the GNU General Public License for more details.
14  */
15 
16 /*
17  * Test for EFAULT when rlim points outside the accessible address space.
18  */
19 
20 #define _GNU_SOURCE
21 #include <errno.h>
22 #include <sys/resource.h>
23 #include <sys/time.h>
24 #include <sys/wait.h>
25 #include <stdlib.h>
26 
27 #include "tst_test.h"
28 
29 static void *bad_addr;
30 
verify_setrlimit(void)31 static void verify_setrlimit(void)
32 {
33 	int status;
34 	pid_t pid;
35 
36 	pid = SAFE_FORK();
37 	if (!pid) {
38 		TEST(setrlimit(RLIMIT_NOFILE, bad_addr));
39 		if (TST_RET != -1) {
40 			tst_res(TFAIL, "setrlimit()  succeeded unexpectedly");
41 			exit(0);
42 		}
43 
44 		/* Usually, setrlimit() should return EFAULT */
45 		if (TST_ERR == EFAULT) {
46 			tst_res(TPASS | TTERRNO,
47 				"setrlimit() failed as expected");
48 		} else {
49 			tst_res(TFAIL | TTERRNO,
50 				"setrlimit() should fail with EFAULT, got");
51 		}
52 
53 		exit(0);
54 	}
55 
56 	SAFE_WAITPID(pid, &status, 0);
57 
58 	/* If glibc has to convert between 32bit and 64bit struct rlimit
59 	 * in some cases, it is possible to get SegFault.
60 	 */
61 	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV) {
62 		tst_res(TPASS, "setrlimit() caused SIGSEGV");
63 		return;
64 	}
65 
66 	if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
67 		return;
68 
69 	tst_res(TBROK, "child %s", tst_strstatus(status));
70 }
71 
setup(void)72 static void setup(void)
73 {
74 	bad_addr = tst_get_bad_addr(NULL);
75 }
76 
77 static struct tst_test test = {
78 	.test_all = verify_setrlimit,
79 	.forks_child = 1,
80 	.setup = setup,
81 };
82