1 /*
2  * Copyright (C) 2008 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 #define ATRACE_TAG ATRACE_TAG_PACKAGE_MANAGER
18 
19 #include "FsCrypt.h"
20 #include "MetadataCrypt.h"
21 #include "NetlinkManager.h"
22 #include "VoldNativeService.h"
23 #include "VoldUtil.h"
24 #include "VolumeManager.h"
25 #include "model/Disk.h"
26 #include "sehandle.h"
27 
28 #include <android-base/logging.h>
29 #include <android-base/properties.h>
30 #include <android-base/stringprintf.h>
31 #include <cutils/klog.h>
32 #include <hidl/HidlTransportSupport.h>
33 #include <utils/Trace.h>
34 
35 #include <dirent.h>
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <fs_mgr.h>
39 #include <getopt.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <sys/stat.h>
44 #include <sys/types.h>
45 
46 typedef struct vold_configs {
47     bool has_adoptable : 1;
48     bool has_quota : 1;
49     bool has_reserved : 1;
50     bool has_compress : 1;
51 } VoldConfigs;
52 
53 static int process_config(VolumeManager* vm, VoldConfigs* configs);
54 static void coldboot(const char* path);
55 static void parse_args(int argc, char** argv);
56 static void VoldLogger(android::base::LogId log_buffer_id, android::base::LogSeverity severity,
57                        const char* tag, const char* file, unsigned int line, const char* message);
58 
59 struct selabel_handle* sehandle;
60 android::base::LogdLogger logd_logger(android::base::SYSTEM);
61 
62 using android::base::StringPrintf;
63 using android::fs_mgr::ReadDefaultFstab;
64 
main(int argc,char ** argv)65 int main(int argc, char** argv) {
66     atrace_set_tracing_enabled(false);
67     setenv("ANDROID_LOG_TAGS", "*:d", 1);  // Do not submit with verbose logs enabled
68     android::base::InitLogging(argv, &VoldLogger);
69 
70     LOG(INFO) << "Vold 3.0 (the awakening) firing up";
71 
72     ATRACE_BEGIN("main");
73 
74     LOG(DEBUG) << "Detected support for:"
75                << (android::vold::IsFilesystemSupported("ext4") ? " ext4" : "")
76                << (android::vold::IsFilesystemSupported("f2fs") ? " f2fs" : "")
77                << (android::vold::IsFilesystemSupported("vfat") ? " vfat" : "");
78 
79     VolumeManager* vm;
80     NetlinkManager* nm;
81 
82     parse_args(argc, argv);
83 
84     sehandle = selinux_android_file_context_handle();
85     if (!sehandle) {
86         LOG(ERROR) << "Failed to get SELinux file contexts handle";
87         exit(1);
88     }
89     selinux_android_set_sehandle(sehandle);
90 
91     mkdir("/dev/block/vold", 0755);
92 
93     /* For when cryptfs checks and mounts an encrypted filesystem */
94     klog_set_level(6);
95 
96     /* Create our singleton managers */
97     if (!(vm = VolumeManager::Instance())) {
98         LOG(ERROR) << "Unable to create VolumeManager";
99         exit(1);
100     }
101 
102     if (!(nm = NetlinkManager::Instance())) {
103         LOG(ERROR) << "Unable to create NetlinkManager";
104         exit(1);
105     }
106 
107     if (android::base::GetBoolProperty("vold.debug", false)) {
108         vm->setDebug(true);
109     }
110 
111     if (vm->start()) {
112         PLOG(ERROR) << "Unable to start VolumeManager";
113         exit(1);
114     }
115 
116     VoldConfigs configs = {};
117     if (process_config(vm, &configs)) {
118         PLOG(ERROR) << "Error reading configuration... continuing anyways";
119     }
120 
121     android::hardware::configureRpcThreadpool(1, false /* callerWillJoin */);
122 
123     ATRACE_BEGIN("VoldNativeService::start");
124     if (android::vold::VoldNativeService::start() != android::OK) {
125         LOG(ERROR) << "Unable to start VoldNativeService";
126         exit(1);
127     }
128     ATRACE_END();
129 
130     LOG(DEBUG) << "VoldNativeService::start() completed OK";
131 
132     ATRACE_BEGIN("NetlinkManager::start");
133     if (nm->start()) {
134         PLOG(ERROR) << "Unable to start NetlinkManager";
135         exit(1);
136     }
137     ATRACE_END();
138 
139     // This call should go after listeners are started to avoid
140     // a deadlock between vold and init (see b/34278978 for details)
141     android::base::SetProperty("vold.has_adoptable", configs.has_adoptable ? "1" : "0");
142     android::base::SetProperty("vold.has_quota", configs.has_quota ? "1" : "0");
143     android::base::SetProperty("vold.has_reserved", configs.has_reserved ? "1" : "0");
144     android::base::SetProperty("vold.has_compress", configs.has_compress ? "1" : "0");
145 
146     // Do coldboot here so it won't block booting,
147     // also the cold boot is needed in case we have flash drive
148     // connected before Vold launched
149     coldboot("/sys/block");
150 
151     ATRACE_END();
152 
153     android::IPCThreadState::self()->joinThreadPool();
154     LOG(INFO) << "vold shutting down";
155 
156     exit(0);
157 }
158 
parse_args(int argc,char ** argv)159 static void parse_args(int argc, char** argv) {
160     static struct option opts[] = {
161         {"blkid_context", required_argument, 0, 'b'},
162         {"blkid_untrusted_context", required_argument, 0, 'B'},
163         {"fsck_context", required_argument, 0, 'f'},
164         {"fsck_untrusted_context", required_argument, 0, 'F'},
165         {nullptr, 0, nullptr, 0},
166     };
167 
168     int c;
169     while ((c = getopt_long(argc, argv, "", opts, nullptr)) != -1) {
170         switch (c) {
171             // clang-format off
172         case 'b': android::vold::sBlkidContext = optarg; break;
173         case 'B': android::vold::sBlkidUntrustedContext = optarg; break;
174         case 'f': android::vold::sFsckContext = optarg; break;
175         case 'F': android::vold::sFsckUntrustedContext = optarg; break;
176                 // clang-format on
177         }
178     }
179 
180     CHECK(android::vold::sBlkidContext != nullptr);
181     CHECK(android::vold::sBlkidUntrustedContext != nullptr);
182     CHECK(android::vold::sFsckContext != nullptr);
183     CHECK(android::vold::sFsckUntrustedContext != nullptr);
184 }
185 
do_coldboot(DIR * d,int lvl)186 static void do_coldboot(DIR* d, int lvl) {
187     struct dirent* de;
188     int dfd, fd;
189 
190     dfd = dirfd(d);
191 
192     fd = openat(dfd, "uevent", O_WRONLY | O_CLOEXEC);
193     if (fd >= 0) {
194         write(fd, "add\n", 4);
195         close(fd);
196     }
197 
198     while ((de = readdir(d))) {
199         DIR* d2;
200 
201         if (de->d_name[0] == '.') continue;
202 
203         if (de->d_type != DT_DIR && lvl > 0) continue;
204 
205         fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
206         if (fd < 0) continue;
207 
208         d2 = fdopendir(fd);
209         if (d2 == 0)
210             close(fd);
211         else {
212             do_coldboot(d2, lvl + 1);
213             closedir(d2);
214         }
215     }
216 }
217 
coldboot(const char * path)218 static void coldboot(const char* path) {
219     ATRACE_NAME("coldboot");
220     DIR* d = opendir(path);
221     if (d) {
222         do_coldboot(d, 0);
223         closedir(d);
224     }
225 }
226 
process_config(VolumeManager * vm,VoldConfigs * configs)227 static int process_config(VolumeManager* vm, VoldConfigs* configs) {
228     ATRACE_NAME("process_config");
229 
230     if (!ReadDefaultFstab(&fstab_default)) {
231         PLOG(ERROR) << "Failed to open default fstab";
232         return -1;
233     }
234 
235     /* Loop through entries looking for ones that vold manages */
236     configs->has_adoptable = false;
237     configs->has_quota = false;
238     configs->has_reserved = false;
239     configs->has_compress = false;
240     for (auto& entry : fstab_default) {
241         if (entry.fs_mgr_flags.quota) {
242             configs->has_quota = true;
243         }
244         if (entry.reserved_size > 0) {
245             configs->has_reserved = true;
246         }
247         if (entry.fs_mgr_flags.fs_compress) {
248             configs->has_compress = true;
249         }
250 
251         /* Make sure logical partitions have an updated blk_device. */
252         if (entry.fs_mgr_flags.logical && !fs_mgr_update_logical_partition(&entry) &&
253             !entry.fs_mgr_flags.no_fail) {
254             PLOG(FATAL) << "could not find logical partition " << entry.blk_device;
255         }
256 
257         if (entry.mount_point == "/data" && !entry.metadata_key_dir.empty()) {
258             // Pre-populate userdata dm-devices since the uevents are asynchronous (b/198405417).
259             android::vold::defaultkey_precreate_dm_device();
260         }
261 
262         if (entry.fs_mgr_flags.vold_managed) {
263             if (entry.fs_mgr_flags.nonremovable) {
264                 LOG(WARNING) << "nonremovable no longer supported; ignoring volume";
265                 continue;
266             }
267 
268             std::string sysPattern(entry.blk_device);
269             std::string nickname(entry.label);
270             int flags = 0;
271 
272             if (entry.is_encryptable()) {
273                 flags |= android::vold::Disk::Flags::kAdoptable;
274                 configs->has_adoptable = true;
275             }
276             if (entry.fs_mgr_flags.no_emulated_sd ||
277                 android::base::GetBoolProperty("vold.debug.default_primary", false)) {
278                 flags |= android::vold::Disk::Flags::kDefaultPrimary;
279             }
280 
281             vm->addDiskSource(std::shared_ptr<VolumeManager::DiskSource>(
282                 new VolumeManager::DiskSource(sysPattern, nickname, flags)));
283         }
284     }
285     return 0;
286 }
287 
VoldLogger(android::base::LogId log_buffer_id,android::base::LogSeverity severity,const char * tag,const char * file,unsigned int line,const char * message)288 static void VoldLogger(android::base::LogId log_buffer_id, android::base::LogSeverity severity,
289                        const char* tag, const char* file, unsigned int line, const char* message) {
290     logd_logger(log_buffer_id, severity, tag, file, line, message);
291 
292     if (severity >= android::base::WARNING) {
293         static bool early_boot_done = false;
294 
295         // If metadata encryption setup (fscrypt_mount_metadata_encrypted) or
296         // basic FBE setup (fscrypt_init_user0) fails, then the boot will fail
297         // before adb can be started, so logcat won't be available.  To allow
298         // debugging these early boot failures, log early errors and warnings to
299         // the kernel log.  This allows diagnosing failures via the serial log,
300         // or via last dmesg/"fastboot oem dmesg" on devices that support it.
301         //
302         // As a very quick-and-dirty test for whether /data has been mounted,
303         // check whether /data/misc/vold exists.
304         if (!early_boot_done) {
305             if (access("/data/misc/vold", F_OK) == 0 && fscrypt_init_user0_done) {
306                 early_boot_done = true;
307                 return;
308             }
309             android::base::KernelLogger(log_buffer_id, severity, tag, file, line, message);
310         }
311     }
312 }
313