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