• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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