xref: /xnu-10002.1.13/tests/nvram_tests/nvram_nonentitled.c (revision 1031c584a5e37aff177559b9f69dbd3c8c3fd30a)
1 #include <darwintest.h>
2 #include "nvram_helper.h"
3 
4 T_GLOBAL_META(T_META_NAMESPACE("xnu.nvram"),
5     T_META_RADAR_COMPONENT_NAME("xnu"),
6     T_META_RADAR_COMPONENT_VERSION("nvram"));
7 
8 static io_registry_entry_t optionsRef = IO_OBJECT_NULL;
9 
10 // xcrun -sdk iphoneos.internal make -C tests nvram_nonentitled && sudo ./tests/build/sym/nvram_nonentitled
11 
12 // Test basic read, write, delete for a random variable
13 T_DECL(TestBasicCmds, "Test basic nvram commands")
14 {
15 	const char *varToTest = "varToTest1";
16 
17 	optionsRef = CreateOptionsRef();
18 
19 	TestVarOp(OP_SET, varToTest, DefaultSetVal, KERN_SUCCESS, optionsRef);
20 	TestVarOp(OP_GET, varToTest, DefaultSetVal, KERN_SUCCESS, optionsRef);
21 	TestVarOp(OP_DEL, varToTest, NULL, KERN_SUCCESS, optionsRef);
22 
23 	ReleaseOptionsRef(optionsRef);
24 }
25 
26 // Test basic read, write, delete for a random variable with random guid
27 T_DECL(TestRandomGuid, "Test random guid")
28 {
29 	const char *varToTest = "11112222-77F8-4392-B4A3-1E7304206516:varToTest3";
30 
31 	optionsRef = CreateOptionsRef();
32 
33 	TestVarOp(OP_SET, varToTest, DefaultSetVal, KERN_SUCCESS, optionsRef);
34 	TestVarOp(OP_GET, varToTest, DefaultSetVal, KERN_SUCCESS, optionsRef);
35 	TestVarOp(OP_DEL, varToTest, NULL, KERN_SUCCESS, optionsRef);
36 
37 	ReleaseOptionsRef(optionsRef);
38 }
39 
40 #if !(__x86_64__)
41 #if (TARGET_OS_OSX)
42 // Test that writing of system variables without system entitlement should fail
43 T_DECL(TestSystem, "Test system guids")
44 {
45 	const char *varToTest = SystemNVRAMGuidString ":" "varToTest2";
46 
47 	optionsRef = CreateOptionsRef();
48 
49 	TestVarOp(OP_SET, varToTest, DefaultSetVal, kIOReturnNotPrivileged, optionsRef);
50 
51 	ReleaseOptionsRef(optionsRef);
52 }
53 #endif /* (TARGET_OS_OSX) */
54 
55 // Test that writing of kernel variables without w/o kernel task should fail
56 T_DECL(TestKernelPrefix, "Test kernel prefix")
57 {
58 	char * varToTest = KernelOnlyVariablePrefix "kernelVar";
59 
60 	optionsRef = CreateOptionsRef();
61 
62 	TestVarOp(OP_SET, varToTest, DefaultSetVal, kIOReturnNotPrivileged, optionsRef);
63 
64 	TestVarOp(OP_GET, varToTest, DefaultSetVal, KERN_FAILURE, optionsRef);
65 
66 	ReleaseOptionsRef(optionsRef);
67 }
68 
69 // Test that variables with KernelOnly bit set cannot be modified from user space
70 T_DECL(TestKernelOnly, "Test variable with TestKernelOnly bit set")
71 {
72 	char * varToTest = "testKernelOnly";
73 
74 	optionsRef = CreateOptionsRef();
75 
76 	TestVarOp(OP_SET, varToTest, DefaultSetVal, kIOReturnNotPrivileged, optionsRef);
77 
78 	ReleaseOptionsRef(optionsRef);
79 }
80 
81 // Test that variables with NeverAllowedToDelete bit set cannot be deleted even with ResetNVram()
82 // To reset nvram, call the test with -r argument:
83 // sudo ./tests/build/sym/nvram_nonentitled -n xnu.nvram.TestImmutable -- -r
84 T_DECL(TestImmutable, "Test immutable variable")
85 {
86 	opterr = 0;
87 	optind = 0;
88 	const char * varToTest = "testNeverDel";
89 
90 	optionsRef = CreateOptionsRef();
91 
92 	TestVarOp(OP_SET, varToTest, DefaultSetVal, KERN_SUCCESS, optionsRef);
93 	TestVarOp(OP_DEL, varToTest, NULL, KERN_FAILURE, optionsRef);
94 
95 	if (getopt(argc, argv, "r") == 'r') {
96 		TestVarOp(OP_RES, NULL, NULL, KERN_SUCCESS, optionsRef);
97 	}
98 	TestVarOp(OP_GET, varToTest, DefaultSetVal, KERN_SUCCESS, optionsRef);
99 
100 	ReleaseOptionsRef(optionsRef);
101 }
102 
103 // Test that variables with ResetNVRAMOnlyDelete bit set can be deleted only by ResetNVram
104 // To reset nvram, call the test with -r argument:
105 // sudo ./tests/build/sym/nvram_nonentitled -n xnu.nvram.TestResetOnlyDel -- -r
106 T_DECL(TestResetOnlyDel, "Test variable with ResetNVRAMOnlyDelete bit set")
107 {
108 	opterr = 0;
109 	optind = 0;
110 	const char * varToTest = "testResetOnlyDel";
111 
112 	optionsRef = CreateOptionsRef();
113 
114 	TestVarOp(OP_SET, varToTest, DefaultSetVal, KERN_SUCCESS, optionsRef);
115 	TestVarOp(OP_DEL, varToTest, NULL, KERN_FAILURE, optionsRef);
116 
117 	if (getopt(argc, argv, "r") == 'r') {
118 		TestVarOp(OP_RES, NULL, NULL, KERN_SUCCESS, optionsRef);
119 		TestVarOp(OP_GET, varToTest, NULL, KERN_FAILURE, optionsRef);
120 	}
121 
122 	ReleaseOptionsRef(optionsRef);
123 }
124 
125 // Test that read of entitled variables without entitlement should fail
126 T_DECL(TestEntRd, "Test read entitled variables")
127 {
128 	char * varToTest = "testEntRd";
129 
130 	optionsRef = CreateOptionsRef();
131 
132 	TestVarOp(OP_SET, varToTest, DefaultSetVal, KERN_SUCCESS, optionsRef);
133 	TestVarOp(OP_GET, varToTest, NULL, KERN_FAILURE, optionsRef);
134 	TestVarOp(OP_DEL, varToTest, NULL, KERN_SUCCESS, optionsRef);
135 
136 	ReleaseOptionsRef(optionsRef);
137 }
138 
139 // Test that writing of entitled variables without entitlement should fail
140 T_DECL(TestEntModRst, "Test write entitled variables")
141 {
142 	char * varToTest = "testEntModRst";
143 
144 	optionsRef = CreateOptionsRef();
145 
146 	TestVarOp(OP_SET, varToTest, DefaultSetVal, kIOReturnNotPrivileged, optionsRef);
147 
148 	ReleaseOptionsRef(optionsRef);
149 }
150 
151 // Test that deleting of entitled variables without entitlement should fail
152 // To reset nvram, call the test with -r argument:
153 // sudo ./tests/build/sym/nvram_nonentitled -n xnu.nvram.TestEntDel -- -r
154 T_DECL(TestEntDel, "Test delete entitled variables")
155 {
156 	opterr = 0;
157 	optind = 0;
158 	char * varToTest = "testEntDel";
159 
160 	optionsRef = CreateOptionsRef();
161 
162 	TestVarOp(OP_SET, varToTest, DefaultSetVal, KERN_SUCCESS, optionsRef);
163 	TestVarOp(OP_DEL, varToTest, NULL, KERN_FAILURE, optionsRef);
164 
165 	if (getopt(argc, argv, "r") == 'r') {
166 		TestVarOp(OP_RES, NULL, NULL, KERN_SUCCESS, optionsRef);
167 		TestVarOp(OP_GET, varToTest, NULL, KERN_FAILURE, optionsRef);
168 	}
169 
170 	ReleaseOptionsRef(optionsRef);
171 }
172 
173 // Test resetting of nvram without entitlement should not erase TestEntRst
174 // To reset nvram, call the test with -r argument:
175 // sudo ./tests/build/sym/nvram_nonentitled -n xnu.nvram.TestEntRst -- -r
176 T_DECL(TestEntRst, "Test reset entitled variables")
177 {
178 	opterr = 0;
179 	optind = 0;
180 	char * varToTest = "testEntRst";
181 
182 	optionsRef = CreateOptionsRef();
183 
184 	TestVarOp(OP_SET, varToTest, DefaultSetVal, KERN_SUCCESS, optionsRef);
185 
186 	if (getopt(argc, argv, "r") == 'r') {
187 		TestVarOp(OP_RES, NULL, NULL, KERN_SUCCESS, optionsRef);
188 		TestVarOp(OP_GET, varToTest, DefaultSetVal, KERN_SUCCESS, optionsRef);
189 	} else {
190 		TestVarOp(OP_DEL, varToTest, NULL, KERN_SUCCESS, optionsRef);
191 		T_PASS("NVram reset not invoked");
192 	}
193 
194 	ReleaseOptionsRef(optionsRef);
195 }
196 
197 // Test nvram types
198 T_DECL(TestTypes, "Test nvram types")
199 {
200 	char * boolVar = "test-bool";
201 	char * numVar  = "test-num";
202 	char * strVar  = "test-str";
203 	char * dataVar = "test-data";
204 
205 	optionsRef = CreateOptionsRef();
206 
207 	TestVarOp(OP_SET, boolVar, "true", KERN_SUCCESS, optionsRef);
208 	TestVarOp(OP_SET, numVar, "123", KERN_SUCCESS, optionsRef);
209 	TestVarOp(OP_SET, strVar, "teststring", KERN_SUCCESS, optionsRef);
210 	TestVarOp(OP_SET, dataVar, "testdata", KERN_SUCCESS, optionsRef);
211 
212 	T_ASSERT_EQ(GetVarType(boolVar, optionsRef), CFBooleanGetTypeID(), "Verified %s type as boolean.\n", boolVar);
213 	T_ASSERT_EQ(GetVarType(numVar, optionsRef), CFNumberGetTypeID(), "Verified %s type as number.\n", numVar);
214 	T_ASSERT_EQ(GetVarType(strVar, optionsRef), CFStringGetTypeID(), "Verified %s type as string.\n", strVar);
215 	T_ASSERT_EQ(GetVarType(dataVar, optionsRef), CFDataGetTypeID(), "Verified %s type as data.\n", dataVar);
216 
217 	TestVarOp(OP_DEL, boolVar, NULL, KERN_SUCCESS, optionsRef);
218 	TestVarOp(OP_DEL, numVar, NULL, KERN_SUCCESS, optionsRef);
219 	TestVarOp(OP_DEL, strVar, NULL, KERN_SUCCESS, optionsRef);
220 	TestVarOp(OP_DEL, dataVar, NULL, KERN_SUCCESS, optionsRef);
221 
222 	ReleaseOptionsRef(optionsRef);
223 }
224 
225 // Test NVRAM Reset
226 // To reset nvram, call the test with -r argument:
227 // sudo ./tests/build/sym/nvram_nonentitled -n xnu.nvram.TestNVRAMReset -- -r
228 T_DECL(TestNVRAMReset, "Test NVRAM Reset")
229 {
230 	opterr = 0;
231 	optind = 0;
232 	const char * varToTest = "testVar1";
233 	const char * varToTestWRand = RandomNVRAMGuidString ":" "testVar2";
234 
235 
236 	optionsRef = CreateOptionsRef();
237 
238 	if (getopt(argc, argv, "r") == 'r') {
239 		TestVarOp(OP_SET, varToTest, DefaultSetVal, KERN_SUCCESS, optionsRef);
240 		TestVarOp(OP_SET, varToTestWRand, DefaultSetVal, KERN_SUCCESS, optionsRef);
241 
242 		TestVarOp(OP_RES, NULL, NULL, KERN_SUCCESS, optionsRef);
243 
244 		TestVarOp(OP_GET, varToTest, NULL, KERN_FAILURE, optionsRef);
245 		TestVarOp(OP_GET, varToTestWRand, NULL, KERN_FAILURE, optionsRef);
246 	} else {
247 		T_PASS("NVram reset not invoked");
248 	}
249 
250 	ReleaseOptionsRef(optionsRef);
251 }
252 
253 // Test NVRAM Obliterate
254 // To obliterate nvram, call the test with -r argument:
255 // sudo ./tests/build/sym/nvram_nonentitled -n xnu.nvram.TestNVRAMOblit -- -r
256 T_DECL(TestNVRAMOblit, "Test NVRAM Obliterate")
257 {
258 	opterr = 0;
259 	optind = 0;
260 	const char * varToTest = "testVar1";
261 	const char * varToTestWRand = RandomNVRAMGuidString ":" "testVar2";
262 	const char * oblitNonSys = CommonNVRAMGuidString ":" "ObliterateNVRam";
263 
264 	optionsRef = CreateOptionsRef();
265 
266 	if (getopt(argc, argv, "r") == 'r') {
267 		TestVarOp(OP_SET, varToTest, DefaultSetVal, KERN_SUCCESS, optionsRef);
268 		TestVarOp(OP_SET, varToTestWRand, DefaultSetVal, KERN_SUCCESS, optionsRef);
269 
270 		TestVarOp(OP_OBL, oblitNonSys, NULL, KERN_SUCCESS, optionsRef);
271 
272 		TestVarOp(OP_GET, varToTest, NULL, KERN_FAILURE, optionsRef);
273 		TestVarOp(OP_GET, varToTestWRand, NULL, KERN_FAILURE, optionsRef);
274 	} else {
275 		T_PASS("NVram obliterate not invoked");
276 	}
277 
278 	ReleaseOptionsRef(optionsRef);
279 }
280 #endif /* !(__x86_64__) */
281