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) 2018 Michael Moese <[email protected]>
4*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) Linux Test Project, 2020
5*49cdfc7eSAndroid Build Coastguard Worker */
6*49cdfc7eSAndroid Build Coastguard Worker
7*49cdfc7eSAndroid Build Coastguard Worker #define TST_NO_DEFAULT_MAIN
8*49cdfc7eSAndroid Build Coastguard Worker
9*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
10*49cdfc7eSAndroid Build Coastguard Worker #include "tst_taint.h"
11*49cdfc7eSAndroid Build Coastguard Worker #include "tst_safe_stdio.h"
12*49cdfc7eSAndroid Build Coastguard Worker
13*49cdfc7eSAndroid Build Coastguard Worker #define TAINT_FILE "/proc/sys/kernel/tainted"
14*49cdfc7eSAndroid Build Coastguard Worker
15*49cdfc7eSAndroid Build Coastguard Worker static unsigned int taint_mask = -1;
16*49cdfc7eSAndroid Build Coastguard Worker
17*49cdfc7eSAndroid Build Coastguard Worker static const char *const taint_strings[] = {
18*49cdfc7eSAndroid Build Coastguard Worker "G (Propriety module loaded)",
19*49cdfc7eSAndroid Build Coastguard Worker "F (Module force loaded)",
20*49cdfc7eSAndroid Build Coastguard Worker "S (Running on out of spec system)",
21*49cdfc7eSAndroid Build Coastguard Worker "R (Module force unloaded)",
22*49cdfc7eSAndroid Build Coastguard Worker "M (Machine check exception)",
23*49cdfc7eSAndroid Build Coastguard Worker "B (Bad page reference)",
24*49cdfc7eSAndroid Build Coastguard Worker "U (User request)",
25*49cdfc7eSAndroid Build Coastguard Worker "D (OOPS/BUG)",
26*49cdfc7eSAndroid Build Coastguard Worker "A (ACPI table overridden)",
27*49cdfc7eSAndroid Build Coastguard Worker "W (Warning)",
28*49cdfc7eSAndroid Build Coastguard Worker "C (Staging driver loaded)",
29*49cdfc7eSAndroid Build Coastguard Worker "I (Workaround BIOS/FW bug)",
30*49cdfc7eSAndroid Build Coastguard Worker "O (Out of tree module loaded)",
31*49cdfc7eSAndroid Build Coastguard Worker "E (Unsigned module loaded)",
32*49cdfc7eSAndroid Build Coastguard Worker "L (Soft lock up occured)",
33*49cdfc7eSAndroid Build Coastguard Worker "K (Live patched)",
34*49cdfc7eSAndroid Build Coastguard Worker "X (Auxilary)",
35*49cdfc7eSAndroid Build Coastguard Worker "T (Built with struct randomization)",
36*49cdfc7eSAndroid Build Coastguard Worker };
37*49cdfc7eSAndroid Build Coastguard Worker
tst_taint_read(void)38*49cdfc7eSAndroid Build Coastguard Worker static unsigned int tst_taint_read(void)
39*49cdfc7eSAndroid Build Coastguard Worker {
40*49cdfc7eSAndroid Build Coastguard Worker unsigned int val;
41*49cdfc7eSAndroid Build Coastguard Worker
42*49cdfc7eSAndroid Build Coastguard Worker SAFE_FILE_SCANF(TAINT_FILE, "%u", &val);
43*49cdfc7eSAndroid Build Coastguard Worker
44*49cdfc7eSAndroid Build Coastguard Worker return val;
45*49cdfc7eSAndroid Build Coastguard Worker }
46*49cdfc7eSAndroid Build Coastguard Worker
tst_taint_check_kver(unsigned int mask)47*49cdfc7eSAndroid Build Coastguard Worker static int tst_taint_check_kver(unsigned int mask)
48*49cdfc7eSAndroid Build Coastguard Worker {
49*49cdfc7eSAndroid Build Coastguard Worker int r1;
50*49cdfc7eSAndroid Build Coastguard Worker int r2;
51*49cdfc7eSAndroid Build Coastguard Worker int r3 = 0;
52*49cdfc7eSAndroid Build Coastguard Worker
53*49cdfc7eSAndroid Build Coastguard Worker if (mask & TST_TAINT_X) {
54*49cdfc7eSAndroid Build Coastguard Worker r1 = 4;
55*49cdfc7eSAndroid Build Coastguard Worker r2 = 15;
56*49cdfc7eSAndroid Build Coastguard Worker } else if (mask & TST_TAINT_K) {
57*49cdfc7eSAndroid Build Coastguard Worker r1 = 4;
58*49cdfc7eSAndroid Build Coastguard Worker r2 = 0;
59*49cdfc7eSAndroid Build Coastguard Worker } else if (mask & TST_TAINT_L) {
60*49cdfc7eSAndroid Build Coastguard Worker r1 = 3;
61*49cdfc7eSAndroid Build Coastguard Worker r2 = 17;
62*49cdfc7eSAndroid Build Coastguard Worker } else if (mask & TST_TAINT_E) {
63*49cdfc7eSAndroid Build Coastguard Worker r1 = 3;
64*49cdfc7eSAndroid Build Coastguard Worker r2 = 15;
65*49cdfc7eSAndroid Build Coastguard Worker } else if (mask & TST_TAINT_O) {
66*49cdfc7eSAndroid Build Coastguard Worker r1 = 3;
67*49cdfc7eSAndroid Build Coastguard Worker r2 = 2;
68*49cdfc7eSAndroid Build Coastguard Worker } else if (mask & TST_TAINT_I) {
69*49cdfc7eSAndroid Build Coastguard Worker r1 = 2;
70*49cdfc7eSAndroid Build Coastguard Worker r2 = 6;
71*49cdfc7eSAndroid Build Coastguard Worker r3 = 35;
72*49cdfc7eSAndroid Build Coastguard Worker } else if (mask & TST_TAINT_C) {
73*49cdfc7eSAndroid Build Coastguard Worker r1 = 2;
74*49cdfc7eSAndroid Build Coastguard Worker r2 = 6;
75*49cdfc7eSAndroid Build Coastguard Worker r3 = 28;
76*49cdfc7eSAndroid Build Coastguard Worker } else if (mask & TST_TAINT_W) {
77*49cdfc7eSAndroid Build Coastguard Worker r1 = 2;
78*49cdfc7eSAndroid Build Coastguard Worker r2 = 6;
79*49cdfc7eSAndroid Build Coastguard Worker r3 = 26;
80*49cdfc7eSAndroid Build Coastguard Worker } else if (mask & TST_TAINT_A) {
81*49cdfc7eSAndroid Build Coastguard Worker r1 = 2;
82*49cdfc7eSAndroid Build Coastguard Worker r2 = 6;
83*49cdfc7eSAndroid Build Coastguard Worker r3 = 25;
84*49cdfc7eSAndroid Build Coastguard Worker } else if (mask & TST_TAINT_D) {
85*49cdfc7eSAndroid Build Coastguard Worker r1 = 2;
86*49cdfc7eSAndroid Build Coastguard Worker r2 = 6;
87*49cdfc7eSAndroid Build Coastguard Worker r3 = 23;
88*49cdfc7eSAndroid Build Coastguard Worker } else if (mask & TST_TAINT_U) {
89*49cdfc7eSAndroid Build Coastguard Worker r1 = 2;
90*49cdfc7eSAndroid Build Coastguard Worker r2 = 6;
91*49cdfc7eSAndroid Build Coastguard Worker r3 = 21;
92*49cdfc7eSAndroid Build Coastguard Worker } else {
93*49cdfc7eSAndroid Build Coastguard Worker r1 = 2;
94*49cdfc7eSAndroid Build Coastguard Worker r2 = 6;
95*49cdfc7eSAndroid Build Coastguard Worker r3 = 16;
96*49cdfc7eSAndroid Build Coastguard Worker }
97*49cdfc7eSAndroid Build Coastguard Worker
98*49cdfc7eSAndroid Build Coastguard Worker return tst_kvercmp(r1, r2, r3);
99*49cdfc7eSAndroid Build Coastguard Worker }
100*49cdfc7eSAndroid Build Coastguard Worker
tst_taint_init(unsigned int mask)101*49cdfc7eSAndroid Build Coastguard Worker void tst_taint_init(unsigned int mask)
102*49cdfc7eSAndroid Build Coastguard Worker {
103*49cdfc7eSAndroid Build Coastguard Worker unsigned int taint = -1;
104*49cdfc7eSAndroid Build Coastguard Worker unsigned long i;
105*49cdfc7eSAndroid Build Coastguard Worker
106*49cdfc7eSAndroid Build Coastguard Worker if (mask == 0)
107*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK, "mask is not allowed to be 0");
108*49cdfc7eSAndroid Build Coastguard Worker
109*49cdfc7eSAndroid Build Coastguard Worker if (tst_taint_check_kver(mask) < 0)
110*49cdfc7eSAndroid Build Coastguard Worker tst_res(TCONF, "Kernel is too old for requested mask");
111*49cdfc7eSAndroid Build Coastguard Worker
112*49cdfc7eSAndroid Build Coastguard Worker taint_mask = mask;
113*49cdfc7eSAndroid Build Coastguard Worker taint = tst_taint_read();
114*49cdfc7eSAndroid Build Coastguard Worker
115*49cdfc7eSAndroid Build Coastguard Worker if (taint & TST_TAINT_W) {
116*49cdfc7eSAndroid Build Coastguard Worker tst_res(TCONF, "Ignoring already set kernel warning taint");
117*49cdfc7eSAndroid Build Coastguard Worker taint_mask &= ~TST_TAINT_W;
118*49cdfc7eSAndroid Build Coastguard Worker }
119*49cdfc7eSAndroid Build Coastguard Worker
120*49cdfc7eSAndroid Build Coastguard Worker if ((taint & taint_mask) != 0) {
121*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < ARRAY_SIZE(taint_strings); i++) {
122*49cdfc7eSAndroid Build Coastguard Worker if (taint & (1 << i))
123*49cdfc7eSAndroid Build Coastguard Worker tst_res(TINFO, "tainted: %s", taint_strings[i]);
124*49cdfc7eSAndroid Build Coastguard Worker }
125*49cdfc7eSAndroid Build Coastguard Worker
126*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK, "Kernel is already tainted");
127*49cdfc7eSAndroid Build Coastguard Worker }
128*49cdfc7eSAndroid Build Coastguard Worker }
129*49cdfc7eSAndroid Build Coastguard Worker
130*49cdfc7eSAndroid Build Coastguard Worker
tst_taint_check(void)131*49cdfc7eSAndroid Build Coastguard Worker unsigned int tst_taint_check(void)
132*49cdfc7eSAndroid Build Coastguard Worker {
133*49cdfc7eSAndroid Build Coastguard Worker unsigned int taint = -1;
134*49cdfc7eSAndroid Build Coastguard Worker
135*49cdfc7eSAndroid Build Coastguard Worker if (taint_mask == (unsigned int) -1)
136*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK, "need to call tst_taint_init() first");
137*49cdfc7eSAndroid Build Coastguard Worker
138*49cdfc7eSAndroid Build Coastguard Worker taint = tst_taint_read();
139*49cdfc7eSAndroid Build Coastguard Worker
140*49cdfc7eSAndroid Build Coastguard Worker return (taint & taint_mask);
141*49cdfc7eSAndroid Build Coastguard Worker }
142