1 /*
2 * Copyright (C) 2024 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 #include <memory>
18 #include <string>
19 #include <dirent.h>
20
21 #include <android-base/file.h>
22 #include <android-base/logging.h>
23 #include <android-base/properties.h>
24
25 #include "storage_files_manager.h"
26 #include "aconfigd_util.h"
27 #include "aconfigd.h"
28
29 using namespace android::base;
30
31 namespace android {
32 namespace aconfigd {
33
34 /// Handle a flag override request
HandleFlagOverride(const StorageRequestMessage::FlagOverrideMessage & msg,StorageReturnMessage & return_msg)35 Result<void> Aconfigd::HandleFlagOverride(
36 const StorageRequestMessage::FlagOverrideMessage& msg,
37 StorageReturnMessage& return_msg) {
38 auto result = storage_files_manager_->UpdateFlagValue(msg.package_name(),
39 msg.flag_name(),
40 msg.flag_value(),
41 msg.is_local());
42 RETURN_IF_ERROR(result, "Failed to set flag override");
43 return_msg.mutable_flag_override_message();
44 return {};
45 }
46
47 /// Handle ota flag staging request
HandleOTAStaging(const StorageRequestMessage::OTAFlagStagingMessage & msg,StorageReturnMessage & return_msg)48 Result<void> Aconfigd::HandleOTAStaging(
49 const StorageRequestMessage::OTAFlagStagingMessage& msg,
50 StorageReturnMessage& return_msg) {
51 auto ota_flags_pb_file = root_dir_ + "/flags/ota.pb";
52 auto result = WritePbToFile<StorageRequestMessage::OTAFlagStagingMessage>(
53 msg, ota_flags_pb_file);
54 RETURN_IF_ERROR(result, "Failed to stage OTA flags");
55 return_msg.mutable_ota_staging_message();
56 return {};
57 }
58
59 /// Handle new storage request
HandleNewStorage(const StorageRequestMessage::NewStorageMessage & msg,StorageReturnMessage & return_msg)60 Result<void> Aconfigd::HandleNewStorage(
61 const StorageRequestMessage::NewStorageMessage& msg,
62 StorageReturnMessage& return_msg) {
63 auto updated = storage_files_manager_->AddOrUpdateStorageFiles(
64 msg.container(), msg.package_map(), msg.flag_map(), msg.flag_value());
65 RETURN_IF_ERROR(updated, "Failed to add or update container");
66
67 auto write_result = storage_files_manager_->WritePersistStorageRecordsToFile(
68 persist_storage_records_);
69 RETURN_IF_ERROR(write_result, "Failed to write to persist storage records");
70
71 auto copy = storage_files_manager_->CreateStorageBootCopy(msg.container());
72 RETURN_IF_ERROR(copy, "Failed to make a boot copy for " + msg.container());
73
74 auto result_msg = return_msg.mutable_new_storage_message();
75 result_msg->set_storage_updated(*updated);
76 return {};
77 }
78
79 /// Handle a flag query request
HandleFlagQuery(const StorageRequestMessage::FlagQueryMessage & msg,StorageReturnMessage & return_msg)80 Result<void> Aconfigd::HandleFlagQuery(
81 const StorageRequestMessage::FlagQueryMessage& msg,
82 StorageReturnMessage& return_msg) {
83 auto snapshot = storage_files_manager_->ListFlag(msg.package_name(), msg.flag_name());
84 RETURN_IF_ERROR(snapshot, "Failed query failed");
85 auto result_msg = return_msg.mutable_flag_query_message();
86 result_msg->set_package_name(snapshot->package_name);
87 result_msg->set_flag_name(snapshot->flag_name);
88 result_msg->set_server_flag_value(snapshot->server_flag_value);
89 result_msg->set_local_flag_value(snapshot->local_flag_value);
90 result_msg->set_boot_flag_value(snapshot->boot_flag_value);
91 result_msg->set_default_flag_value(snapshot->default_flag_value);
92 result_msg->set_has_server_override(snapshot->has_server_override);
93 result_msg->set_is_readwrite(snapshot->is_readwrite);
94 result_msg->set_has_local_override(snapshot->has_local_override);
95 return {};
96 }
97
98 /// Handle override removal request
HandleLocalOverrideRemoval(const StorageRequestMessage::RemoveLocalOverrideMessage & msg,StorageReturnMessage & return_msg)99 Result<void> Aconfigd::HandleLocalOverrideRemoval(
100 const StorageRequestMessage::RemoveLocalOverrideMessage& msg,
101 StorageReturnMessage& return_msg) {
102 auto result = Result<void>();
103 if (msg.remove_all()) {
104 result = storage_files_manager_->RemoveAllLocalOverrides();
105 } else {
106 result = storage_files_manager_->RemoveFlagLocalOverride(
107 msg.package_name(), msg.flag_name());
108 }
109 RETURN_IF_ERROR(result, "");
110 return_msg.mutable_remove_local_override_message();
111 return {};
112 }
113
114 /// Handle storage reset
HandleStorageReset(StorageReturnMessage & return_msg)115 Result<void> Aconfigd::HandleStorageReset(StorageReturnMessage& return_msg) {
116 auto result = storage_files_manager_->ResetAllStorage();
117 RETURN_IF_ERROR(result, "Failed to reset all storage");
118
119 result = storage_files_manager_->WritePersistStorageRecordsToFile(
120 persist_storage_records_);
121 RETURN_IF_ERROR(result, "Failed to write persist storage records");
122
123 return_msg.mutable_reset_storage_message();
124 return {};
125 }
126
127 /// Handle list storage
HandleListStorage(const StorageRequestMessage::ListStorageMessage & msg,StorageReturnMessage & return_message)128 Result<void> Aconfigd::HandleListStorage(
129 const StorageRequestMessage::ListStorageMessage& msg,
130 StorageReturnMessage& return_message) {
131 auto flags = Result<std::vector<StorageFiles::FlagSnapshot>>();
132 switch (msg.msg_case()) {
133 case StorageRequestMessage::ListStorageMessage::kAll: {
134 flags = storage_files_manager_->ListAllAvailableFlags();
135 break;
136 }
137 case StorageRequestMessage::ListStorageMessage::kContainer: {
138 flags = storage_files_manager_->ListFlagsInContainer(msg.container());
139 break;
140 }
141 case StorageRequestMessage::ListStorageMessage::kPackageName: {
142 flags = storage_files_manager_->ListFlagsInPackage(msg.package_name());
143 break;
144 }
145 default:
146 return Error() << "Unknown list storage message type from aconfigd socket";
147 }
148 RETURN_IF_ERROR(flags, "Failed to list flags");
149
150 auto* result_msg = return_message.mutable_list_storage_message();
151 for (const auto& flag : *flags) {
152 auto* flag_msg = result_msg->add_flags();
153 flag_msg->set_package_name(flag.package_name);
154 flag_msg->set_flag_name(flag.flag_name);
155 flag_msg->set_server_flag_value(flag.server_flag_value);
156 flag_msg->set_local_flag_value(flag.local_flag_value);
157 flag_msg->set_boot_flag_value(flag.boot_flag_value);
158 flag_msg->set_default_flag_value(flag.default_flag_value);
159 flag_msg->set_is_readwrite(flag.is_readwrite);
160 flag_msg->set_has_server_override(flag.has_server_override);
161 flag_msg->set_has_local_override(flag.has_local_override);
162 }
163 return {};
164 }
165
166 /// Read OTA flag overrides to be applied for current build
ReadOTAFlagOverridesToApply()167 Result<std::vector<FlagOverride>> Aconfigd::ReadOTAFlagOverridesToApply() {
168 auto ota_flags = std::vector<FlagOverride>();
169 auto ota_flags_pb_file = root_dir_ + "/flags/ota.pb";
170 if (FileExists(ota_flags_pb_file)) {
171 auto build_id = GetProperty("ro.build.fingerprint", "");
172 auto ota_flags_pb = ReadPbFromFile<StorageRequestMessage::OTAFlagStagingMessage>(
173 ota_flags_pb_file);
174 RETURN_IF_ERROR(ota_flags_pb, "Failed to read ota flags from pb file");
175 if (ota_flags_pb->build_id() == build_id) {
176 for (const auto& entry : ota_flags_pb->overrides()) {
177 ota_flags.push_back(entry);
178 }
179 }
180 }
181 return ota_flags;
182 }
183
184 /// Write remaining OTA flag overrides back to pb file
WriteRemainingOTAOverrides(const std::vector<FlagOverride> & ota_flags)185 Result<void> Aconfigd::WriteRemainingOTAOverrides(
186 const std::vector<FlagOverride>& ota_flags) {
187 auto ota_flags_pb_file = root_dir_ + "/flags/ota.pb";
188
189 if (!ota_flags.empty()) {
190 auto ota_flags_pb = StorageRequestMessage::OTAFlagStagingMessage();
191 auto build_id = GetProperty("ro.build.fingerprint", "");
192 ota_flags_pb.set_build_id(build_id);
193 for (auto const& entry : ota_flags) {
194 auto* flag = ota_flags_pb.add_overrides();
195 flag->set_package_name(entry.package_name());
196 flag->set_flag_name(entry.flag_name());
197 flag->set_flag_value(entry.flag_value());
198 }
199 auto result = WritePbToFile<StorageRequestMessage::OTAFlagStagingMessage>(
200 ota_flags_pb, ota_flags_pb_file);
201 RETURN_IF_ERROR(result, "Failed to write remaining staged OTA flags");
202 } else {
203 if (FileExists(ota_flags_pb_file)) {
204 unlink(ota_flags_pb_file.c_str());
205 }
206 }
207
208 return {};
209 }
210
211 /// Initialize in memory aconfig storage records
InitializeInMemoryStorageRecords()212 Result<void> Aconfigd::InitializeInMemoryStorageRecords() {
213 // remove old records pb
214 if (FileExists("/metadata/aconfig/persistent_storage_file_records.pb")) {
215 unlink("/metadata/aconfig/persistent_storage_file_records.pb");
216 }
217
218 // remove old records pb
219 if (FileExists("/metadata/aconfig/persist_storage_file_records.pb")) {
220 unlink("/metadata/aconfig/persist_storage_file_records.pb");
221 }
222
223 auto records_pb = ReadPbFromFile<PersistStorageRecords>(persist_storage_records_);
224 RETURN_IF_ERROR(records_pb, "Unable to read persistent storage records");
225 for (const auto& entry : records_pb->records()) {
226 storage_files_manager_->RestoreStorageFiles(entry);
227 }
228 return {};
229 }
230
231 /// Initialize platform RO partition flag storage
InitializePlatformStorage()232 Result<void> Aconfigd::InitializePlatformStorage() {
233 auto init_result = InitializeInMemoryStorageRecords();
234 RETURN_IF_ERROR(init_result, "Failed to init from persist stoage records");
235
236 auto remove_result = RemoveFilesInDir(root_dir_ + "/boot");
237 RETURN_IF_ERROR(remove_result, "Failed to clean boot dir");
238
239 auto ota_flags = ReadOTAFlagOverridesToApply();
240 RETURN_IF_ERROR(ota_flags, "Failed to get remaining staged OTA flags");
241 bool apply_ota_flag = !(ota_flags->empty());
242
243 auto value_files = std::vector<std::pair<std::string, std::string>>{
244 {"system", "/system/etc/aconfig"},
245 {"system_ext", "/system_ext/etc/aconfig"},
246 {"vendor", "/vendor/etc/aconfig"},
247 {"product", "/product/etc/aconfig"}};
248
249 for (auto const& [container, storage_dir] : value_files) {
250 auto package_file = std::string(storage_dir) + "/package.map";
251 auto flag_file = std::string(storage_dir) + "/flag.map";
252 auto value_file = std::string(storage_dir) + "/flag.val";
253
254 if (!FileNonZeroSize(value_file)) {
255 continue;
256 }
257
258 auto updated = storage_files_manager_->AddOrUpdateStorageFiles(
259 container, package_file, flag_file, value_file);
260 RETURN_IF_ERROR(updated, "Failed to add or update storage for container "
261 + container);
262
263 if (apply_ota_flag) {
264 ota_flags = storage_files_manager_->ApplyOTAFlagsForContainer(
265 container, *ota_flags);
266 RETURN_IF_ERROR(ota_flags, "Failed to apply staged OTA flags");
267 }
268
269 auto write_result = storage_files_manager_->WritePersistStorageRecordsToFile(
270 persist_storage_records_);
271 RETURN_IF_ERROR(write_result, "Failed to write to persist storage records");
272
273 auto copied = storage_files_manager_->CreateStorageBootCopy(container);
274 RETURN_IF_ERROR(copied, "Failed to create boot snapshot for container "
275 + container);
276 }
277
278 if (apply_ota_flag) {
279 auto result = WriteRemainingOTAOverrides(*ota_flags);
280 RETURN_IF_ERROR(result, "Failed to write remaining staged OTA flags");
281 }
282
283 return {};
284 }
285
286 /// Initialize mainline flag storage
InitializeMainlineStorage()287 Result<void> Aconfigd::InitializeMainlineStorage() {
288 auto init_result = InitializeInMemoryStorageRecords();
289 RETURN_IF_ERROR(init_result, "Failed to init from persist stoage records");
290
291 auto ota_flags = ReadOTAFlagOverridesToApply();
292 RETURN_IF_ERROR(ota_flags, "Failed to get remaining staged OTA flags");
293 bool apply_ota_flag = !(ota_flags->empty());
294
295 auto apex_dir = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/apex"), closedir);
296 if (!apex_dir) {
297 return {};
298 }
299
300 struct dirent* entry;
301 while ((entry = readdir(apex_dir.get())) != nullptr) {
302 if (entry->d_type != DT_DIR) continue;
303
304 auto container = std::string(entry->d_name);
305 if (container[0] == '.') continue;
306 if (container.find('@') != std::string::npos) continue;
307 if (container == "sharedlibs") continue;
308
309 auto storage_dir = std::string("/apex/") + container + "/etc";
310 auto package_file = std::string(storage_dir) + "/package.map";
311 auto flag_file = std::string(storage_dir) + "/flag.map";
312 auto value_file = std::string(storage_dir) + "/flag.val";
313
314 if (!FileExists(value_file) || !FileNonZeroSize(value_file)) {
315 continue;
316 }
317
318 auto updated = storage_files_manager_->AddOrUpdateStorageFiles(
319 container, package_file, flag_file, value_file);
320 RETURN_IF_ERROR(updated, "Failed to add or update storage for container "
321 + container);
322
323 if (apply_ota_flag) {
324 ota_flags = storage_files_manager_->ApplyOTAFlagsForContainer(
325 container, *ota_flags);
326 RETURN_IF_ERROR(ota_flags, "Failed to apply staged OTA flags");
327 }
328
329 auto write_result = storage_files_manager_->WritePersistStorageRecordsToFile(
330 persist_storage_records_);
331 RETURN_IF_ERROR(write_result, "Failed to write to persist storage records");
332
333 auto copied = storage_files_manager_->CreateStorageBootCopy(container);
334 RETURN_IF_ERROR(copied, "Failed to create boot snapshot for container "
335 + container);
336 }
337
338 if (apply_ota_flag) {
339 auto result = WriteRemainingOTAOverrides(*ota_flags);
340 RETURN_IF_ERROR(result, "Failed to write remaining staged OTA flags");
341 }
342
343 return {};
344 }
345
346 /// Handle incoming messages to aconfigd socket
HandleSocketRequest(const StorageRequestMessage & message,StorageReturnMessage & return_message)347 Result<void> Aconfigd::HandleSocketRequest(const StorageRequestMessage& message,
348 StorageReturnMessage& return_message) {
349 auto result = Result<void>();
350
351 switch (message.msg_case()) {
352 case StorageRequestMessage::kNewStorageMessage: {
353 auto msg = message.new_storage_message();
354 LOG(INFO) << "received a new storage request for " << msg.container()
355 << " with storage files " << msg.package_map() << " "
356 << msg.flag_map() << " " << msg.flag_value();
357 result = HandleNewStorage(msg, return_message);
358 break;
359 }
360 case StorageRequestMessage::kFlagOverrideMessage: {
361 auto msg = message.flag_override_message();
362 LOG(INFO) << "received a" << (msg.is_local() ? " local " : " server ")
363 << "flag override request for " << msg.package_name() << "/"
364 << msg.flag_name() << " to " << msg.flag_value();
365 result = HandleFlagOverride(msg, return_message);
366 break;
367 }
368 case StorageRequestMessage::kOtaStagingMessage: {
369 auto msg = message.ota_staging_message();
370 LOG(INFO) << "received ota flag staging requests for " << msg.build_id();
371 result = HandleOTAStaging(msg, return_message);
372 break;
373 }
374 case StorageRequestMessage::kFlagQueryMessage: {
375 auto msg = message.flag_query_message();
376 LOG(INFO) << "received a flag query request for " << msg.package_name()
377 << "/" << msg.flag_name();
378 result = HandleFlagQuery(msg, return_message);
379 break;
380 }
381 case StorageRequestMessage::kRemoveLocalOverrideMessage: {
382 auto msg = message.remove_local_override_message();
383 if (msg.remove_all()) {
384 LOG(INFO) << "received a global local override removal request";
385 } else {
386 LOG(INFO) << "received local override removal request for "
387 << msg.package_name() << "/" << msg.flag_name();
388 }
389 result = HandleLocalOverrideRemoval(msg, return_message);
390 break;
391 }
392 case StorageRequestMessage::kResetStorageMessage: {
393 LOG(INFO) << "received reset storage request";
394 result = HandleStorageReset(return_message);
395 break;
396 }
397 case StorageRequestMessage::kListStorageMessage: {
398 auto msg = message.list_storage_message();
399 LOG(INFO) << "received list storage request";
400 result = HandleListStorage(msg, return_message);
401 break;
402 }
403 default:
404 result = Error() << "Unknown message type from aconfigd socket";
405 break;
406 }
407
408 return result;
409 }
410
411 } // namespace aconfigd
412 } // namespace android
413