Home | History | Annotate | Download | only in thp
      1 /*
      2  * This is a reproducer of CVE-2011-0999, which fixed by mainline commit
      3  * a7d6e4ecdb7648478ddec76d30d87d03d6e22b31:
      4  *
      5  * "Transparent hugepages can only be created if rmap is fully
      6  * functional. So we must prevent hugepages to be created while
      7  * is_vma_temporary_stack() is true."
      8  *
      9  * It will cause a panic something like this, if the patch didn't get
     10  * applied:
     11  *
     12  * kernel BUG at mm/huge_memory.c:1260!
     13  * invalid opcode: 0000 [#1] SMP
     14  * last sysfs file: /sys/devices/system/cpu/cpu23/cache/index2/shared_cpu_map
     15  * ....
     16  *
     17  * Copyright (C) 2011  Red Hat, Inc.
     18  * This program is free software; you can redistribute it and/or
     19  * modify it under the terms of version 2 of the GNU General Public
     20  * License as published by the Free Software Foundation.
     21  *
     22  * This program is distributed in the hope that it would be useful,
     23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     25  *
     26  * Further, this software is distributed without any warranty that it
     27  * is free of the rightful claim of any third person regarding
     28  * infringement or the like.  Any license provided herein, whether
     29  * implied or otherwise, applies only to this software file.  Patent
     30  * licenses, if any, provided herein do not apply to combinations of
     31  * this program with other software, or any other product whatsoever.
     32  *
     33  * You should have received a copy of the GNU General Public License
     34  * along with this program; if not, write the Free Software
     35  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
     36  * 02110-1301, USA.
     37  */
     38 
     39 #include <sys/types.h>
     40 #include <sys/resource.h>
     41 #include <sys/wait.h>
     42 #include <stdio.h>
     43 #include <string.h>
     44 #include <unistd.h>
     45 #include "test.h"
     46 
     47 char *TCID = "thp01";
     48 int TST_TOTAL = 1;
     49 
     50 #define ARRAY_SZ	256
     51 
     52 static int ps;
     53 static long length;
     54 static char *array[ARRAY_SZ];
     55 static char *arg;
     56 static struct rlimit rl = {
     57 	.rlim_cur = RLIM_INFINITY,
     58 	.rlim_max = RLIM_INFINITY,
     59 };
     60 
     61 static void setup(void);
     62 static void cleanup(void);
     63 
     64 int main(int argc, char **argv)
     65 {
     66 	int i, lc, st;
     67 	pid_t pid;
     68 
     69 	tst_parse_opts(argc, argv, NULL, NULL);
     70 
     71 	setup();
     72 
     73 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     74 		switch (pid = fork()) {
     75 		case -1:
     76 			tst_brkm(TBROK | TERRNO, cleanup, "fork");
     77 		case 0:
     78 			memset(arg, 'c', length - 1);
     79 			arg[length - 1] = '\0';
     80 			array[0] = "true";
     81 			for (i = 1; i < ARRAY_SZ - 1; i++)
     82 				array[i] = arg;
     83 			array[ARRAY_SZ - 1] = NULL;
     84 			if (setrlimit(RLIMIT_STACK, &rl) == -1) {
     85 				perror("setrlimit");
     86 				exit(1);
     87 			}
     88 			if (execvp("true", array) == -1) {
     89 				perror("execvp");
     90 				exit(1);
     91 			}
     92 		default:
     93 			if (waitpid(pid, &st, 0) == -1)
     94 				tst_brkm(TBROK | TERRNO, cleanup, "waitpid");
     95 			if (!WIFEXITED(st) || WEXITSTATUS(st) != 0)
     96 				tst_brkm(TBROK, cleanup,
     97 					 "child exited abnormally");
     98 		}
     99 	}
    100 	tst_resm(TPASS, "system didn't crash, pass.");
    101 	cleanup();
    102 	tst_exit();
    103 }
    104 
    105 static void setup(void)
    106 {
    107 	ps = sysconf(_SC_PAGESIZE);
    108 	length = 32 * ps;
    109 	arg = malloc(length);
    110 	if (arg == NULL)
    111 		tst_brkm(TBROK | TERRNO, NULL, "malloc");
    112 
    113 	tst_sig(FORK, DEF_HANDLER, cleanup);
    114 	TEST_PAUSE;
    115 }
    116 
    117 static void cleanup(void)
    118 {
    119 }
    120