1 /* 2 * Copyright (C) 2025 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 #ifndef ART_RUNTIME_OAT_SDC_FILE_H_ 18 #define ART_RUNTIME_OAT_SDC_FILE_H_ 19 20 #include <memory> 21 #include <string> 22 #include <string_view> 23 #include <utility> 24 25 #include "base/macros.h" 26 #include "base/os.h" 27 28 namespace art HIDDEN { 29 30 // A helper class to read a secure dex metadata companion (SDC) file. 31 // 32 // Secure dex metadata companion (SDC) file is a file type that augments a secure dex metadata (SDM) 33 // file with additional metadata. 34 // 35 // 1. There may be exactly one SDC file accompanying each SDM file. An SDC file without a 36 // corresponding SDM file, or with a mismatching SDM timestamp, is garbage. 37 // 2. They are always local on device. 38 // 3. They are only read and written by the ART module. 39 // 4. A later version of the ART module must be able to understand the contents. 40 // 41 // It is a text file in the format of: 42 // key1=value1\n 43 // key2=value2\n 44 // ... 45 // Repeated keys are not allowed. This is an extensible format, so versioning is not needed. 46 // 47 // In principle, ART Service generates an SDC file for an SDM file during installation. 48 // Specifically, during dexopt, which typically takes place during installation, if there is an SDM 49 // file while the corresponding SDC file is missing (meaning the SDM file is newly installed) or 50 // stale (meaning the SDM file is newly replaced), ART Service will generate a new SDC file. This 51 // means an SDM file without a corresponding SDC file is a transient state and is valid from ART 52 // Service's perspective. 53 // 54 // From the runtime's perspective, an SDM file without a corresponding SDC file is incomplete. That 55 // means: 56 // - At app execution time, the runtime ignores an SDM file without a corresponding SDC. 57 // - ART Service's file GC, which uses the runtime's judgement, considers an SDM file without a 58 // corresponding SDC invalid and may clean it up. This may race with a package installation before 59 // the SDC is created, but it's rare and the effect is recoverable, so it's considered acceptable. 60 class EXPORT SdcReader { 61 public: 62 static std::unique_ptr<SdcReader> Load(const std::string& filename, std::string* error_msg); 63 64 // The mtime of the SDM file on device, in nanoseconds. 65 // This is for detecting obsolete SDC files. GetSdmTimestampNs()66 int64_t GetSdmTimestampNs() const { return sdm_timestamp_ns_; } 67 68 // The value of `Runtime::GetApexVersions` at the time where the SDM file was first seen on 69 // device. This is for detecting samegrade placebos. GetApexVersions()70 std::string_view GetApexVersions() const { return apex_versions_; } 71 72 private: 73 SdcReader() = default; 74 75 std::string content_; 76 int64_t sdm_timestamp_ns_; 77 std::string_view apex_versions_; 78 }; 79 80 // A helper class to write a secure dex metadata companion (SDC) file. 81 class EXPORT SdcWriter { 82 public: 83 // Takes ownership of the file. SdcWriter(File && file)84 explicit SdcWriter(File&& file) : file_(std::move(file)) {} 85 86 // See `SdcReader::GetSdmTimestampNs`. SetSdmTimestampNs(int64_t value)87 void SetSdmTimestampNs(int64_t value) { sdm_timestamp_ns_ = value; } 88 89 // See `SdcReader::GetApexVersions`. SetApexVersions(std::string_view value)90 void SetApexVersions(std::string_view value) { apex_versions_ = value; } 91 92 bool Save(std::string* error_msg); 93 94 private: 95 File file_; 96 int64_t sdm_timestamp_ns_ = 0; 97 std::string apex_versions_; 98 }; 99 100 } // namespace art 101 102 #endif // ART_RUNTIME_OAT_SDC_FILE_H_ 103