1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) Zilogic Systems Pvt. Ltd, 2020. All Rights Reserved.
4 * Email: <code@zilogic.com>
5 *
6 * Based on testcases/kernel/syscalls/adjtimex/adjtimex01.c
7 * Copyright (c) Wipro Technologies Ltd, 2002.
8 *
9 * CVE-2018-11508
10 *
11 * Test 4-byte kernel data leak via adjtimex
12 *
13 * On calling the adjtimex() function call with invalid mode (let's say
14 * 0x8000), ideally all the parameters should return with null data. But,
15 * when we read the last parameter we will receive 4 bytes of kernel data.
16 * This proves that there are 4 bytes of info leaked. The bug was fixed in
17 * Kernel Version 4.16.9. Therefore, the below test case will only be
18 * applicable for the kernel version 4.16.9 and above.
19 *
20 * So basically, this test shall check whether there is any data leak.
21 * To test that, Pass struct timex buffer filled with zero with
22 * some INVALID mode to the system call adjtimex. Passing an invalid
23 * parameters will not call do_adjtimex() and before that, it shall throw
24 * an error(On error test shall not break). Therefore, none of the parameters
25 * will get initialized.
26 *
27 * On reading the last attribute tai of the struct, if the attribute is non-
28 * zero the test is considered to have failed, else the test is considered
29 * to have passed.
30 */
31
32 #include <errno.h>
33 #include <sys/timex.h>
34 #include "tst_test.h"
35
36 #define ADJ_ADJTIME 0x8000
37 #define LOOPS 10
38
39 static struct timex *buf;
40
verify_adjtimex(void)41 void verify_adjtimex(void)
42 {
43 int i;
44 int data_leak = 0;
45
46 for (i = 0; i < LOOPS; i++) {
47 memset(buf, 0, sizeof(struct timex));
48 buf->modes = ADJ_ADJTIME; /* Invalid mode */
49 TEST(adjtimex(buf));
50 if ((TST_RET == -1) && (TST_ERR == EINVAL)) {
51 tst_res(TINFO,
52 "expecting adjtimex() to fail with EINVAL with mode 0x%x",
53 ADJ_ADJTIME);
54 } else {
55 tst_brk(TBROK | TERRNO,
56 "adjtimex(): Unexpeceted error, expecting EINVAL with mode 0x%x",
57 ADJ_ADJTIME);
58 }
59
60 tst_res(TINFO, "tai : 0x%08x", buf->tai);
61
62 if (buf->tai != 0) {
63 data_leak = 1;
64 break;
65 }
66 }
67 if (data_leak != 0)
68 tst_res(TFAIL, "Data leak observed");
69 else
70 tst_res(TPASS, "Data leak not observed");
71 }
72
73 static struct tst_test test = {
74 .test_all = verify_adjtimex,
75 .bufs = (struct tst_buffers []) {
76 {&buf, .size = sizeof(*buf)},
77 {},
78 },
79 .tags = (const struct tst_tag[]) {
80 {"CVE", "2018-11508"},
81 {"linux-git", "0a0b98734479"},
82 {},
83 }
84 };
85