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