Home | History | Annotate | Download | only in setrlimit
      1 /*
      2  * Copyright (c) 2017 FUJITSU LIMITED. All rights reserved.
      3  * Author: Xiao Yang <yangx.jy (at) 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 verify_setrlimit(void)
     30 {
     31 	int status;
     32 	pid_t pid;
     33 
     34 	pid = SAFE_FORK();
     35 	if (!pid) {
     36 		TEST(setrlimit(RLIMIT_NOFILE, (void *) -1));
     37 		if (TEST_RETURN != -1) {
     38 			tst_res(TFAIL, "setrlimit()  succeeded unexpectedly");
     39 			exit(0);
     40 		}
     41 
     42 		/* Usually, setrlimit() should return EFAULT */
     43 		if (TEST_ERRNO == EFAULT) {
     44 			tst_res(TPASS | TTERRNO,
     45 				"setrlimit() failed as expected");
     46 		} else {
     47 			tst_res(TFAIL | TTERRNO,
     48 				"setrlimit() should fail with EFAULT, got");
     49 		}
     50 
     51 		exit(0);
     52 	}
     53 
     54 	SAFE_WAITPID(pid, &status, 0);
     55 
     56 	/* If glibc has to convert between 32bit and 64bit struct rlimit
     57 	 * in some cases, it is possible to get SegFault.
     58 	 */
     59 	if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV) {
     60 		tst_res(TPASS, "setrlimit() caused SIGSEGV");
     61 		return;
     62 	}
     63 
     64 	if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
     65 		return;
     66 
     67 	tst_res(TBROK, "child %s", tst_strstatus(status));
     68 }
     69 
     70 static struct tst_test test = {
     71 	.test_all = verify_setrlimit,
     72 	.forks_child = 1,
     73 };
     74