blob: 6fbd208860a4eadd591daefb7a58dfbdcbecf0b1 [file] [log] [blame]
Jan Stancekcf18a592014-08-05 13:30:37 +02001/*
2 * Copyright (c) Linux Test Project, 2014
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Library General Public License for more details.
13 */
14/*
15 * This is a regression test for madvise(2) system call. It tests kernel
16 * for NULL ptr deref Oops fixed by:
17 * commit ee53664bda169f519ce3c6a22d378f0b946c8178
18 * Author: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
19 * Date: Fri Dec 20 15:10:03 2013 +0200
20 * mm: Fix NULL pointer dereference in madvise(MADV_WILLNEED) support
21 *
22 * On buggy kernel with CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_DEBUG_LOCK_ALLOC=y
23 * this testcase should produce Oops and/or be killed. On fixed/good kernel
24 * this testcase runs to completion (retcode is 0)
25 */
26
27#include <sys/mman.h>
28#include <errno.h>
29
30#include "test.h"
Jan Stancekcf18a592014-08-05 13:30:37 +020031#include "safe_macros.h"
32
33#define ALLOC_SIZE (32 * 1024 * 1024)
34
35static void setup(void);
36static void cleanup(void);
37
38char *TCID = "madvise05";
39int TST_TOTAL = 1;
40
41int main(int argc, char *argv[])
42{
43 int lc;
44 const char *msg = NULL;
45 void *p;
46
47 msg = parse_opts(argc, argv, NULL, NULL);
48 if (msg)
49 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
50
51 setup();
52
53 for (lc = 0; TEST_LOOPING(lc); lc++) {
54 p = SAFE_MMAP(cleanup, NULL, ALLOC_SIZE, PROT_READ,
55 MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
56 TEST(mprotect(p, ALLOC_SIZE, PROT_NONE));
57 if (TEST_RETURN == -1)
58 tst_brkm(TBROK | TTERRNO, cleanup, "mprotect failed");
59 TEST(madvise(p, ALLOC_SIZE, MADV_WILLNEED));
60 SAFE_MUNMAP(cleanup, p, ALLOC_SIZE);
61
62 if (TEST_RETURN == 0)
63 continue;
64
65 if (TEST_ERRNO == EBADF)
66 tst_brkm(TCONF, cleanup, "CONFIG_SWAP=n");
67 else
68 tst_brkm(TBROK | TTERRNO, cleanup, "madvise failed");
69 }
70
71 tst_resm(TPASS, "issue has not been reproduced");
72
73 cleanup();
74 tst_exit();
75}
76
77static void setup(void)
78{
79 tst_sig(NOFORK, DEF_HANDLER, cleanup);
80 if (tst_kvercmp(3, 9, 0) < 0)
81 tst_brkm(TCONF, NULL, "madvise(MADV_WILLNEED) swap file "
82 "prefetch available only since 3.9");
83 TEST_PAUSE;
84}
85
86static void cleanup(void)
87{
Jan Stancekcf18a592014-08-05 13:30:37 +020088}