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