1 #define TST_NO_DEFAULT_MAIN
2
3 #include "tst_test.h"
4 #include "tst_taint.h"
5 #include "tst_safe_stdio.h"
6
7 #define TAINT_FILE "/proc/sys/kernel/tainted"
8
9 static unsigned int taint_mask = -1;
10
tst_taint_read(void)11 static unsigned int tst_taint_read(void)
12 {
13 unsigned int val;
14
15 SAFE_FILE_SCANF(TAINT_FILE, "%u", &val);
16
17 return val;
18 }
19
tst_taint_check_kver(unsigned int mask)20 static int tst_taint_check_kver(unsigned int mask)
21 {
22 int r1;
23 int r2;
24 int r3 = 0;
25
26 if (mask & TST_TAINT_X) {
27 r1 = 4;
28 r2 = 15;
29 } else if (mask & TST_TAINT_K) {
30 r1 = 4;
31 r2 = 0;
32 } else if (mask & TST_TAINT_L) {
33 r1 = 3;
34 r2 = 17;
35 } else if (mask & TST_TAINT_E) {
36 r1 = 3;
37 r2 = 15;
38 } else if (mask & TST_TAINT_O) {
39 r1 = 3;
40 r2 = 2;
41 } else if (mask & TST_TAINT_I) {
42 r1 = 2;
43 r2 = 6;
44 r3 = 35;
45 } else if (mask & TST_TAINT_C) {
46 r1 = 2;
47 r2 = 6;
48 r3 = 28;
49 } else if (mask & TST_TAINT_W) {
50 r1 = 2;
51 r2 = 6;
52 r3 = 26;
53 } else if (mask & TST_TAINT_A) {
54 r1 = 2;
55 r2 = 6;
56 r3 = 25;
57 } else if (mask & TST_TAINT_D) {
58 r1 = 2;
59 r2 = 6;
60 r3 = 23;
61 } else if (mask & TST_TAINT_U) {
62 r1 = 2;
63 r2 = 6;
64 r3 = 21;
65 } else {
66 r1 = 2;
67 r2 = 6;
68 r3 = 16;
69 }
70
71 return tst_kvercmp(r1, r2, r3);
72 }
73
tst_taint_init(unsigned int mask)74 void tst_taint_init(unsigned int mask)
75 {
76 unsigned int taint = -1;
77
78 if (mask == 0)
79 tst_brk(TBROK, "mask is not allowed to be 0");
80
81 if (tst_taint_check_kver(mask) < 0)
82 tst_res(TCONF, "Kernel is too old for requested mask");
83
84 taint_mask = mask;
85 taint = tst_taint_read();
86
87 if (taint & TST_TAINT_W) {
88 tst_res(TCONF, "Ignoring already set kernel warning taint");
89 taint_mask &= ~TST_TAINT_W;
90 }
91
92 if ((taint & taint_mask) != 0)
93 tst_brk(TBROK, "Kernel is already tainted: %u", taint);
94 }
95
96
tst_taint_check(void)97 unsigned int tst_taint_check(void)
98 {
99 unsigned int taint = -1;
100
101 if (taint_mask == (unsigned int) -1)
102 tst_brk(TBROK, "need to call tst_taint_init() first");
103
104 taint = tst_taint_read();
105
106 return (taint & taint_mask);
107 }
108