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