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