1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // This file contains the functions that initialize SELinux during boot as well as helper functions 18 // for SELinux operation for init. 19 20 // When the system boots, there is no SEPolicy present and init is running in the kernel domain. 21 // Init loads the SEPolicy from the file system, restores the context of /init based on this 22 // SEPolicy, and finally exec()'s itself to run in the proper domain. 23 24 // The SEPolicy on Android comes in two variants: monolithic and split. 25 26 // The monolithic policy variant is for legacy non-treble devices that contain a single SEPolicy 27 // file located at /sepolicy and is directly loaded into the kernel SELinux subsystem. 28 29 // The split policy is for supporting treble devices. It splits the SEPolicy across files on 30 // /system/etc/selinux (the 'plat' portion of the policy) and /vendor/etc/selinux (the 'nonplat' 31 // portion of the policy). This is necessary to allow the system image to be updated independently 32 // of the vendor image, while maintaining contributions from both partitions in the SEPolicy. This 33 // is especially important for VTS testing, where the SEPolicy on the Google System Image may not be 34 // identical to the system image shipped on a vendor's device. 35 36 // The split SEPolicy is loaded as described below: 37 // 1) There is a precompiled SEPolicy located at /vendor/etc/selinux/precompiled_sepolicy. 38 // Stored along with this file is the sha256 hash of the parts of the SEPolicy on /system that 39 // were used to compile this precompiled policy. The system partition contains a similar sha256 40 // of the parts of the SEPolicy that it currently contains. If these two hashes match, then the 41 // system loads this precompiled_sepolicy directly. 42 // 2) If these hashes do not match, then /system has been updated out of sync with /vendor and the 43 // init needs to compile the SEPolicy. /system contains the SEPolicy compiler, secilc, and it 44 // is used by the LoadSplitPolicy() function below to compile the SEPolicy to a temp directory 45 // and load it. That function contains even more documentation with the specific implementation 46 // details of how the SEPolicy is compiled if needed. 47 48 #include "selinux.h" 49 50 #include <fcntl.h> 51 #include <stdlib.h> 52 #include <sys/wait.h> 53 #include <unistd.h> 54 55 #include <android-base/chrono_utils.h> 56 #include <android-base/file.h> 57 #include <android-base/logging.h> 58 #include <android-base/parseint.h> 59 #include <android-base/unique_fd.h> 60 #include <selinux/android.h> 61 62 #include "log.h" 63 #include "util.h" 64 65 using android::base::ParseInt; 66 using android::base::Timer; 67 using android::base::unique_fd; 68 69 namespace android { 70 namespace init { 71 72 namespace { 73 74 selabel_handle* sehandle = nullptr; 75 76 enum EnforcingStatus { SELINUX_PERMISSIVE, SELINUX_ENFORCING }; 77 78 EnforcingStatus StatusFromCmdline() { 79 EnforcingStatus status = SELINUX_ENFORCING; 80 81 import_kernel_cmdline(false, 82 [&](const std::string& key, const std::string& value, bool in_qemu) { 83 if (key == "androidboot.selinux" && value == "permissive") { 84 status = SELINUX_PERMISSIVE; 85 } 86 }); 87 88 return status; 89 } 90 91 bool IsEnforcing() { 92 if (ALLOW_PERMISSIVE_SELINUX) { 93 return StatusFromCmdline() == SELINUX_ENFORCING; 94 } 95 return true; 96 } 97 98 // Forks, executes the provided program in the child, and waits for the completion in the parent. 99 // Child's stderr is captured and logged using LOG(ERROR). 100 bool ForkExecveAndWaitForCompletion(const char* filename, char* const argv[]) { 101 // Create a pipe used for redirecting child process's output. 102 // * pipe_fds[0] is the FD the parent will use for reading. 103 // * pipe_fds[1] is the FD the child will use for writing. 104 int pipe_fds[2]; 105 if (pipe(pipe_fds) == -1) { 106 PLOG(ERROR) << "Failed to create pipe"; 107 return false; 108 } 109 110 pid_t child_pid = fork(); 111 if (child_pid == -1) { 112 PLOG(ERROR) << "Failed to fork for " << filename; 113 return false; 114 } 115 116 if (child_pid == 0) { 117 // fork succeeded -- this is executing in the child process 118 119 // Close the pipe FD not used by this process 120 close(pipe_fds[0]); 121 122 // Redirect stderr to the pipe FD provided by the parent 123 if (TEMP_FAILURE_RETRY(dup2(pipe_fds[1], STDERR_FILENO)) == -1) { 124 PLOG(ERROR) << "Failed to redirect stderr of " << filename; 125 _exit(127); 126 return false; 127 } 128 close(pipe_fds[1]); 129 130 if (execv(filename, argv) == -1) { 131 PLOG(ERROR) << "Failed to execve " << filename; 132 return false; 133 } 134 // Unreachable because execve will have succeeded and replaced this code 135 // with child process's code. 136 _exit(127); 137 return false; 138 } else { 139 // fork succeeded -- this is executing in the original/parent process 140 141 // Close the pipe FD not used by this process 142 close(pipe_fds[1]); 143 144 // Log the redirected output of the child process. 145 // It's unfortunate that there's no standard way to obtain an istream for a file descriptor. 146 // As a result, we're buffering all output and logging it in one go at the end of the 147 // invocation, instead of logging it as it comes in. 148 const int child_out_fd = pipe_fds[0]; 149 std::string child_output; 150 if (!android::base::ReadFdToString(child_out_fd, &child_output)) { 151 PLOG(ERROR) << "Failed to capture full output of " << filename; 152 } 153 close(child_out_fd); 154 if (!child_output.empty()) { 155 // Log captured output, line by line, because LOG expects to be invoked for each line 156 std::istringstream in(child_output); 157 std::string line; 158 while (std::getline(in, line)) { 159 LOG(ERROR) << filename << ": " << line; 160 } 161 } 162 163 // Wait for child to terminate 164 int status; 165 if (TEMP_FAILURE_RETRY(waitpid(child_pid, &status, 0)) != child_pid) { 166 PLOG(ERROR) << "Failed to wait for " << filename; 167 return false; 168 } 169 170 if (WIFEXITED(status)) { 171 int status_code = WEXITSTATUS(status); 172 if (status_code == 0) { 173 return true; 174 } else { 175 LOG(ERROR) << filename << " exited with status " << status_code; 176 } 177 } else if (WIFSIGNALED(status)) { 178 LOG(ERROR) << filename << " killed by signal " << WTERMSIG(status); 179 } else if (WIFSTOPPED(status)) { 180 LOG(ERROR) << filename << " stopped by signal " << WSTOPSIG(status); 181 } else { 182 LOG(ERROR) << "waitpid for " << filename << " returned unexpected status: " << status; 183 } 184 185 return false; 186 } 187 } 188 189 bool ReadFirstLine(const char* file, std::string* line) { 190 line->clear(); 191 192 std::string contents; 193 if (!android::base::ReadFileToString(file, &contents, true /* follow symlinks */)) { 194 return false; 195 } 196 std::istringstream in(contents); 197 std::getline(in, *line); 198 return true; 199 } 200 201 bool FindPrecompiledSplitPolicy(std::string* file) { 202 file->clear(); 203 // If there is an odm partition, precompiled_sepolicy will be in 204 // odm/etc/selinux. Otherwise it will be in vendor/etc/selinux. 205 static constexpr const char vendor_precompiled_sepolicy[] = 206 "/vendor/etc/selinux/precompiled_sepolicy"; 207 static constexpr const char odm_precompiled_sepolicy[] = 208 "/odm/etc/selinux/precompiled_sepolicy"; 209 if (access(odm_precompiled_sepolicy, R_OK) == 0) { 210 *file = odm_precompiled_sepolicy; 211 } else if (access(vendor_precompiled_sepolicy, R_OK) == 0) { 212 *file = vendor_precompiled_sepolicy; 213 } else { 214 PLOG(INFO) << "No precompiled sepolicy"; 215 return false; 216 } 217 std::string actual_plat_id; 218 if (!ReadFirstLine("/system/etc/selinux/plat_and_mapping_sepolicy.cil.sha256", &actual_plat_id)) { 219 PLOG(INFO) << "Failed to read " 220 "/system/etc/selinux/plat_and_mapping_sepolicy.cil.sha256"; 221 return false; 222 } 223 224 std::string precompiled_plat_id; 225 std::string precompiled_sha256 = *file + ".plat_and_mapping.sha256"; 226 if (!ReadFirstLine(precompiled_sha256.c_str(), &precompiled_plat_id)) { 227 PLOG(INFO) << "Failed to read " << precompiled_sha256; 228 file->clear(); 229 return false; 230 } 231 if ((actual_plat_id.empty()) || (actual_plat_id != precompiled_plat_id)) { 232 file->clear(); 233 return false; 234 } 235 return true; 236 } 237 238 bool GetVendorMappingVersion(std::string* plat_vers) { 239 if (!ReadFirstLine("/vendor/etc/selinux/plat_sepolicy_vers.txt", plat_vers)) { 240 PLOG(ERROR) << "Failed to read /vendor/etc/selinux/plat_sepolicy_vers.txt"; 241 return false; 242 } 243 if (plat_vers->empty()) { 244 LOG(ERROR) << "No version present in plat_sepolicy_vers.txt"; 245 return false; 246 } 247 return true; 248 } 249 250 constexpr const char plat_policy_cil_file[] = "/system/etc/selinux/plat_sepolicy.cil"; 251 252 bool IsSplitPolicyDevice() { 253 return access(plat_policy_cil_file, R_OK) != -1; 254 } 255 256 bool LoadSplitPolicy() { 257 // IMPLEMENTATION NOTE: Split policy consists of three CIL files: 258 // * platform -- policy needed due to logic contained in the system image, 259 // * non-platform -- policy needed due to logic contained in the vendor image, 260 // * mapping -- mapping policy which helps preserve forward-compatibility of non-platform policy 261 // with newer versions of platform policy. 262 // 263 // secilc is invoked to compile the above three policy files into a single monolithic policy 264 // file. This file is then loaded into the kernel. 265 266 // Load precompiled policy from vendor image, if a matching policy is found there. The policy 267 // must match the platform policy on the system image. 268 std::string precompiled_sepolicy_file; 269 if (FindPrecompiledSplitPolicy(&precompiled_sepolicy_file)) { 270 unique_fd fd(open(precompiled_sepolicy_file.c_str(), O_RDONLY | O_CLOEXEC | O_BINARY)); 271 if (fd != -1) { 272 if (selinux_android_load_policy_from_fd(fd, precompiled_sepolicy_file.c_str()) < 0) { 273 LOG(ERROR) << "Failed to load SELinux policy from " << precompiled_sepolicy_file; 274 return false; 275 } 276 return true; 277 } 278 } 279 // No suitable precompiled policy could be loaded 280 281 LOG(INFO) << "Compiling SELinux policy"; 282 283 // Determine the highest policy language version supported by the kernel 284 set_selinuxmnt("/sys/fs/selinux"); 285 int max_policy_version = security_policyvers(); 286 if (max_policy_version == -1) { 287 PLOG(ERROR) << "Failed to determine highest policy version supported by kernel"; 288 return false; 289 } 290 291 // We store the output of the compilation on /dev because this is the most convenient tmpfs 292 // storage mount available this early in the boot sequence. 293 char compiled_sepolicy[] = "/dev/sepolicy.XXXXXX"; 294 unique_fd compiled_sepolicy_fd(mkostemp(compiled_sepolicy, O_CLOEXEC)); 295 if (compiled_sepolicy_fd < 0) { 296 PLOG(ERROR) << "Failed to create temporary file " << compiled_sepolicy; 297 return false; 298 } 299 300 // Determine which mapping file to include 301 std::string vend_plat_vers; 302 if (!GetVendorMappingVersion(&vend_plat_vers)) { 303 return false; 304 } 305 std::string mapping_file("/system/etc/selinux/mapping/" + vend_plat_vers + ".cil"); 306 307 // vendor_sepolicy.cil and plat_pub_versioned.cil are the new design to replace 308 // nonplat_sepolicy.cil. 309 std::string plat_pub_versioned_cil_file("/vendor/etc/selinux/plat_pub_versioned.cil"); 310 std::string vendor_policy_cil_file("/vendor/etc/selinux/vendor_sepolicy.cil"); 311 312 if (access(vendor_policy_cil_file.c_str(), F_OK) == -1) { 313 // For backward compatibility. 314 // TODO: remove this after no device is using nonplat_sepolicy.cil. 315 vendor_policy_cil_file = "/vendor/etc/selinux/nonplat_sepolicy.cil"; 316 plat_pub_versioned_cil_file.clear(); 317 } else if (access(plat_pub_versioned_cil_file.c_str(), F_OK) == -1) { 318 LOG(ERROR) << "Missing " << plat_pub_versioned_cil_file; 319 return false; 320 } 321 322 // odm_sepolicy.cil is default but optional. 323 std::string odm_policy_cil_file("/odm/etc/selinux/odm_sepolicy.cil"); 324 if (access(odm_policy_cil_file.c_str(), F_OK) == -1) { 325 odm_policy_cil_file.clear(); 326 } 327 const std::string version_as_string = std::to_string(max_policy_version); 328 329 // clang-format off 330 std::vector<const char*> compile_args { 331 "/system/bin/secilc", 332 plat_policy_cil_file, 333 "-m", "-M", "true", "-G", "-N", 334 // Target the highest policy language version supported by the kernel 335 "-c", version_as_string.c_str(), 336 mapping_file.c_str(), 337 "-o", compiled_sepolicy, 338 // We don't care about file_contexts output by the compiler 339 "-f", "/sys/fs/selinux/null", // /dev/null is not yet available 340 }; 341 // clang-format on 342 343 if (!plat_pub_versioned_cil_file.empty()) { 344 compile_args.push_back(plat_pub_versioned_cil_file.c_str()); 345 } 346 if (!vendor_policy_cil_file.empty()) { 347 compile_args.push_back(vendor_policy_cil_file.c_str()); 348 } 349 if (!odm_policy_cil_file.empty()) { 350 compile_args.push_back(odm_policy_cil_file.c_str()); 351 } 352 compile_args.push_back(nullptr); 353 354 if (!ForkExecveAndWaitForCompletion(compile_args[0], (char**)compile_args.data())) { 355 unlink(compiled_sepolicy); 356 return false; 357 } 358 unlink(compiled_sepolicy); 359 360 LOG(INFO) << "Loading compiled SELinux policy"; 361 if (selinux_android_load_policy_from_fd(compiled_sepolicy_fd, compiled_sepolicy) < 0) { 362 LOG(ERROR) << "Failed to load SELinux policy from " << compiled_sepolicy; 363 return false; 364 } 365 366 return true; 367 } 368 369 bool LoadMonolithicPolicy() { 370 LOG(VERBOSE) << "Loading SELinux policy from monolithic file"; 371 if (selinux_android_load_policy() < 0) { 372 PLOG(ERROR) << "Failed to load monolithic SELinux policy"; 373 return false; 374 } 375 return true; 376 } 377 378 bool LoadPolicy() { 379 return IsSplitPolicyDevice() ? LoadSplitPolicy() : LoadMonolithicPolicy(); 380 } 381 382 } // namespace 383 384 void SelinuxInitialize() { 385 Timer t; 386 387 LOG(INFO) << "Loading SELinux policy"; 388 if (!LoadPolicy()) { 389 LOG(FATAL) << "Unable to load SELinux policy"; 390 } 391 392 bool kernel_enforcing = (security_getenforce() == 1); 393 bool is_enforcing = IsEnforcing(); 394 if (kernel_enforcing != is_enforcing) { 395 if (security_setenforce(is_enforcing)) { 396 PLOG(FATAL) << "security_setenforce(%s) failed" << (is_enforcing ? "true" : "false"); 397 } 398 } 399 400 if (auto result = WriteFile("/sys/fs/selinux/checkreqprot", "0"); !result) { 401 LOG(FATAL) << "Unable to write to /sys/fs/selinux/checkreqprot: " << result.error(); 402 } 403 404 // init's first stage can't set properties, so pass the time to the second stage. 405 setenv("INIT_SELINUX_TOOK", std::to_string(t.duration().count()).c_str(), 1); 406 } 407 408 // The files and directories that were created before initial sepolicy load or 409 // files on ramdisk need to have their security context restored to the proper 410 // value. This must happen before /dev is populated by ueventd. 411 void SelinuxRestoreContext() { 412 LOG(INFO) << "Running restorecon..."; 413 selinux_android_restorecon("/dev", 0); 414 selinux_android_restorecon("/dev/kmsg", 0); 415 if constexpr (WORLD_WRITABLE_KMSG) { 416 selinux_android_restorecon("/dev/kmsg_debug", 0); 417 } 418 selinux_android_restorecon("/dev/socket", 0); 419 selinux_android_restorecon("/dev/random", 0); 420 selinux_android_restorecon("/dev/urandom", 0); 421 selinux_android_restorecon("/dev/__properties__", 0); 422 423 selinux_android_restorecon("/plat_file_contexts", 0); 424 selinux_android_restorecon("/nonplat_file_contexts", 0); 425 selinux_android_restorecon("/vendor_file_contexts", 0); 426 selinux_android_restorecon("/plat_property_contexts", 0); 427 selinux_android_restorecon("/nonplat_property_contexts", 0); 428 selinux_android_restorecon("/vendor_property_contexts", 0); 429 selinux_android_restorecon("/plat_seapp_contexts", 0); 430 selinux_android_restorecon("/nonplat_seapp_contexts", 0); 431 selinux_android_restorecon("/vendor_seapp_contexts", 0); 432 selinux_android_restorecon("/plat_service_contexts", 0); 433 selinux_android_restorecon("/nonplat_service_contexts", 0); 434 selinux_android_restorecon("/vendor_service_contexts", 0); 435 selinux_android_restorecon("/plat_hwservice_contexts", 0); 436 selinux_android_restorecon("/nonplat_hwservice_contexts", 0); 437 selinux_android_restorecon("/vendor_hwservice_contexts", 0); 438 selinux_android_restorecon("/sepolicy", 0); 439 selinux_android_restorecon("/vndservice_contexts", 0); 440 441 selinux_android_restorecon("/dev/block", SELINUX_ANDROID_RESTORECON_RECURSE); 442 selinux_android_restorecon("/dev/device-mapper", 0); 443 444 selinux_android_restorecon("/sbin/mke2fs_static", 0); 445 selinux_android_restorecon("/sbin/e2fsdroid_static", 0); 446 447 selinux_android_restorecon("/sbin/mkfs.f2fs", 0); 448 selinux_android_restorecon("/sbin/sload.f2fs", 0); 449 } 450 451 // This function sets up SELinux logging to be written to kmsg, to match init's logging. 452 void SelinuxSetupKernelLogging() { 453 selinux_callback cb; 454 cb.func_log = selinux_klog_callback; 455 selinux_set_callback(SELINUX_CB_LOG, cb); 456 } 457 458 // This function checks whether the sepolicy supports vendor init. 459 bool SelinuxHasVendorInit() { 460 if (!IsSplitPolicyDevice()) { 461 // If this device does not split sepolicy files, vendor_init will be available in the latest 462 // monolithic sepolicy file. 463 return true; 464 } 465 466 std::string version; 467 if (!GetVendorMappingVersion(&version)) { 468 // Return true as the default if we failed to load the vendor sepolicy version. 469 return true; 470 } 471 472 int major_version; 473 std::string major_version_str(version, 0, version.find('.')); 474 if (!ParseInt(major_version_str, &major_version)) { 475 PLOG(ERROR) << "Failed to parse the vendor sepolicy major version " << major_version_str; 476 // Return true as the default if we failed to parse the major version. 477 return true; 478 } 479 480 return major_version >= 28; 481 } 482 483 // selinux_android_file_context_handle() takes on the order of 10+ms to run, so we want to cache 484 // its value. selinux_android_restorecon() also needs an sehandle for file context look up. It 485 // will create and store its own copy, but selinux_android_set_sehandle() can be used to provide 486 // one, thus eliminating an extra call to selinux_android_file_context_handle(). 487 void SelabelInitialize() { 488 sehandle = selinux_android_file_context_handle(); 489 selinux_android_set_sehandle(sehandle); 490 } 491 492 // A C++ wrapper around selabel_lookup() using the cached sehandle. 493 // If sehandle is null, this returns success with an empty context. 494 bool SelabelLookupFileContext(const std::string& key, int type, std::string* result) { 495 result->clear(); 496 497 if (!sehandle) return true; 498 499 char* context; 500 if (selabel_lookup(sehandle, &context, key.c_str(), type) != 0) { 501 return false; 502 } 503 *result = context; 504 free(context); 505 return true; 506 } 507 508 // A C++ wrapper around selabel_lookup_best_match() using the cached sehandle. 509 // If sehandle is null, this returns success with an empty context. 510 bool SelabelLookupFileContextBestMatch(const std::string& key, 511 const std::vector<std::string>& aliases, int type, 512 std::string* result) { 513 result->clear(); 514 515 if (!sehandle) return true; 516 517 std::vector<const char*> c_aliases; 518 for (const auto& alias : aliases) { 519 c_aliases.emplace_back(alias.c_str()); 520 } 521 c_aliases.emplace_back(nullptr); 522 523 char* context; 524 if (selabel_lookup_best_match(sehandle, &context, key.c_str(), &c_aliases[0], type) != 0) { 525 return false; 526 } 527 *result = context; 528 free(context); 529 return true; 530 } 531 532 } // namespace init 533 } // namespace android 534