1 /*
2  * Copyright (C) 2014 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 <ctype.h>
18 #include <dirent.h>
19 #include <errno.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/mount.h>
24 #include <unistd.h>
25 
26 #include <algorithm>
27 #include <utility>
28 #include <vector>
29 
30 #include <android-base/file.h>
31 #include <android-base/stringprintf.h>
32 #include <android-base/strings.h>
33 
34 #include "fs_mgr_priv.h"
35 
36 const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android");
37 
38 struct fs_mgr_flag_values {
39     char *key_loc;
40     char* key_dir;
41     char *verity_loc;
42     char *sysfs_path;
43     long long part_length;
44     char *label;
45     int partnum;
46     int swap_prio;
47     int max_comp_streams;
48     unsigned int zram_size;
49     uint64_t reserved_size;
50     unsigned int file_contents_mode;
51     unsigned int file_names_mode;
52     unsigned int erase_blk_size;
53     unsigned int logical_blk_size;
54 };
55 
56 struct flag_list {
57     const char *name;
58     unsigned int flag;
59 };
60 
61 static struct flag_list mount_flags[] = {
62     { "noatime",    MS_NOATIME },
63     { "noexec",     MS_NOEXEC },
64     { "nosuid",     MS_NOSUID },
65     { "nodev",      MS_NODEV },
66     { "nodiratime", MS_NODIRATIME },
67     { "ro",         MS_RDONLY },
68     { "rw",         0 },
69     { "remount",    MS_REMOUNT },
70     { "bind",       MS_BIND },
71     { "rec",        MS_REC },
72     { "unbindable", MS_UNBINDABLE },
73     { "private",    MS_PRIVATE },
74     { "slave",      MS_SLAVE },
75     { "shared",     MS_SHARED },
76     { "defaults",   0 },
77     { 0,            0 },
78 };
79 
80 static struct flag_list fs_mgr_flags[] = {
81     {"wait", MF_WAIT},
82     {"check", MF_CHECK},
83     {"encryptable=", MF_CRYPT},
84     {"forceencrypt=", MF_FORCECRYPT},
85     {"fileencryption=", MF_FILEENCRYPTION},
86     {"forcefdeorfbe=", MF_FORCEFDEORFBE},
87     {"keydirectory=", MF_KEYDIRECTORY},
88     {"nonremovable", MF_NONREMOVABLE},
89     {"voldmanaged=", MF_VOLDMANAGED},
90     {"length=", MF_LENGTH},
91     {"recoveryonly", MF_RECOVERYONLY},
92     {"swapprio=", MF_SWAPPRIO},
93     {"zramsize=", MF_ZRAMSIZE},
94     {"max_comp_streams=", MF_MAX_COMP_STREAMS},
95     {"verifyatboot", MF_VERIFYATBOOT},
96     {"verify", MF_VERIFY},
97     {"avb", MF_AVB},
98     {"noemulatedsd", MF_NOEMULATEDSD},
99     {"notrim", MF_NOTRIM},
100     {"formattable", MF_FORMATTABLE},
101     {"slotselect", MF_SLOTSELECT},
102     {"nofail", MF_NOFAIL},
103     {"latemount", MF_LATEMOUNT},
104     {"reservedsize=", MF_RESERVEDSIZE},
105     {"quota", MF_QUOTA},
106     {"eraseblk=", MF_ERASEBLKSIZE},
107     {"logicalblk=", MF_LOGICALBLKSIZE},
108     {"sysfs_path=", MF_SYSFS},
109     {"defaults", 0},
110     {0, 0},
111 };
112 
113 #define EM_AES_256_XTS  1
114 #define EM_ICE          2
115 #define EM_AES_256_CTS  3
116 #define EM_AES_256_HEH  4
117 #define EM_SPECK_128_256_XTS 5
118 #define EM_SPECK_128_256_CTS 6
119 
120 static const struct flag_list file_contents_encryption_modes[] = {
121     {"aes-256-xts", EM_AES_256_XTS},
122     {"speck128/256-xts", EM_SPECK_128_256_XTS},
123     {"software", EM_AES_256_XTS}, /* alias for backwards compatibility */
124     {"ice", EM_ICE},              /* hardware-specific inline cryptographic engine */
125     {0, 0},
126 };
127 
128 static const struct flag_list file_names_encryption_modes[] = {
129     {"aes-256-cts", EM_AES_256_CTS},
130     {"aes-256-heh", EM_AES_256_HEH},
131     {"speck128/256-cts", EM_SPECK_128_256_CTS},
132     {0, 0},
133 };
134 
encryption_mode_to_flag(const struct flag_list * list,const char * mode,const char * type)135 static unsigned int encryption_mode_to_flag(const struct flag_list *list,
136                                             const char *mode, const char *type)
137 {
138     const struct flag_list *j;
139 
140     for (j = list; j->name; ++j) {
141         if (!strcmp(mode, j->name)) {
142             return j->flag;
143         }
144     }
145     LERROR << "Unknown " << type << " encryption mode: " << mode;
146     return 0;
147 }
148 
flag_to_encryption_mode(const struct flag_list * list,unsigned int flag)149 static const char *flag_to_encryption_mode(const struct flag_list *list,
150                                            unsigned int flag)
151 {
152     const struct flag_list *j;
153 
154     for (j = list; j->name; ++j) {
155         if (flag == j->flag) {
156             return j->name;
157         }
158     }
159     return nullptr;
160 }
161 
calculate_zram_size(unsigned int percentage)162 static uint64_t calculate_zram_size(unsigned int percentage)
163 {
164     uint64_t total;
165 
166     total  = sysconf(_SC_PHYS_PAGES);
167     total *= percentage;
168     total /= 100;
169 
170     total *= sysconf(_SC_PAGESIZE);
171 
172     return total;
173 }
174 
parse_size(const char * arg)175 static uint64_t parse_size(const char *arg)
176 {
177     char *endptr;
178     uint64_t size = strtoull(arg, &endptr, 10);
179     if (*endptr == 'k' || *endptr == 'K')
180         size *= 1024LL;
181     else if (*endptr == 'm' || *endptr == 'M')
182         size *= 1024LL * 1024LL;
183     else if (*endptr == 'g' || *endptr == 'G')
184         size *= 1024LL * 1024LL * 1024LL;
185 
186     return size;
187 }
188 
189 /* fills 'dt_value' with the underlying device tree value string without
190  * the trailing '\0'. Returns true if 'dt_value' has a valid string, 'false'
191  * otherwise.
192  */
read_dt_file(const std::string & file_name,std::string * dt_value)193 static bool read_dt_file(const std::string& file_name, std::string* dt_value)
194 {
195     if (android::base::ReadFileToString(file_name, dt_value)) {
196         if (!dt_value->empty()) {
197             // trim the trailing '\0' out, otherwise the comparison
198             // will produce false-negatives.
199             dt_value->resize(dt_value->size() - 1);
200             return true;
201         }
202     }
203 
204     return false;
205 }
206 
parse_flags(char * flags,struct flag_list * fl,struct fs_mgr_flag_values * flag_vals,char * fs_options,int fs_options_len)207 static int parse_flags(char *flags, struct flag_list *fl,
208                        struct fs_mgr_flag_values *flag_vals,
209                        char *fs_options, int fs_options_len)
210 {
211     int f = 0;
212     int i;
213     char *p;
214     char *savep;
215 
216     /* initialize flag values.  If we find a relevant flag, we'll
217      * update the value */
218     if (flag_vals) {
219         memset(flag_vals, 0, sizeof(*flag_vals));
220         flag_vals->partnum = -1;
221         flag_vals->swap_prio = -1; /* negative means it wasn't specified. */
222     }
223 
224     /* initialize fs_options to the null string */
225     if (fs_options && (fs_options_len > 0)) {
226         fs_options[0] = '\0';
227     }
228 
229     p = strtok_r(flags, ",", &savep);
230     while (p) {
231         /* Look for the flag "p" in the flag list "fl"
232          * If not found, the loop exits with fl[i].name being null.
233          */
234         for (i = 0; fl[i].name; i++) {
235             if (!strncmp(p, fl[i].name, strlen(fl[i].name))) {
236                 f |= fl[i].flag;
237                 if ((fl[i].flag == MF_CRYPT) && flag_vals) {
238                     /* The encryptable flag is followed by an = and the
239                      * location of the keys.  Get it and return it.
240                      */
241                     flag_vals->key_loc = strdup(strchr(p, '=') + 1);
242                 } else if ((fl[i].flag == MF_VERIFY) && flag_vals) {
243                     /* If the verify flag is followed by an = and the
244                      * location for the verity state,  get it and return it.
245                      */
246                     char *start = strchr(p, '=');
247                     if (start) {
248                         flag_vals->verity_loc = strdup(start + 1);
249                     }
250                 } else if ((fl[i].flag == MF_FORCECRYPT) && flag_vals) {
251                     /* The forceencrypt flag is followed by an = and the
252                      * location of the keys.  Get it and return it.
253                      */
254                     flag_vals->key_loc = strdup(strchr(p, '=') + 1);
255                 } else if ((fl[i].flag == MF_FORCEFDEORFBE) && flag_vals) {
256                     /* The forcefdeorfbe flag is followed by an = and the
257                      * location of the keys.  Get it and return it.
258                      */
259                     flag_vals->key_loc = strdup(strchr(p, '=') + 1);
260                     flag_vals->file_contents_mode = EM_AES_256_XTS;
261                     flag_vals->file_names_mode = EM_AES_256_CTS;
262                 } else if ((fl[i].flag == MF_FILEENCRYPTION) && flag_vals) {
263                     /* The fileencryption flag is followed by an = and
264                      * the mode of contents encryption, then optionally a
265                      * : and the mode of filenames encryption (defaults
266                      * to aes-256-cts).  Get it and return it.
267                      */
268                     char *mode = strchr(p, '=') + 1;
269                     char *colon = strchr(mode, ':');
270                     if (colon) {
271                         *colon = '\0';
272                     }
273                     flag_vals->file_contents_mode =
274                         encryption_mode_to_flag(file_contents_encryption_modes,
275                                                 mode, "file contents");
276                     if (colon) {
277                         flag_vals->file_names_mode =
278                             encryption_mode_to_flag(file_names_encryption_modes,
279                                                     colon + 1, "file names");
280                     } else {
281                         flag_vals->file_names_mode = EM_AES_256_CTS;
282                     }
283                 } else if ((fl[i].flag == MF_KEYDIRECTORY) && flag_vals) {
284                     /* The metadata flag is followed by an = and the
285                      * directory for the keys.  Get it and return it.
286                      */
287                     flag_vals->key_dir = strdup(strchr(p, '=') + 1);
288                 } else if ((fl[i].flag == MF_LENGTH) && flag_vals) {
289                     /* The length flag is followed by an = and the
290                      * size of the partition.  Get it and return it.
291                      */
292                     flag_vals->part_length = strtoll(strchr(p, '=') + 1, NULL, 0);
293                 } else if ((fl[i].flag == MF_VOLDMANAGED) && flag_vals) {
294                     /* The voldmanaged flag is followed by an = and the
295                      * label, a colon and the partition number or the
296                      * word "auto", e.g.
297                      *   voldmanaged=sdcard:3
298                      * Get and return them.
299                      */
300                     char *label_start;
301                     char *label_end;
302                     char *part_start;
303 
304                     label_start = strchr(p, '=') + 1;
305                     label_end = strchr(p, ':');
306                     if (label_end) {
307                         flag_vals->label = strndup(label_start,
308                                                    (int) (label_end - label_start));
309                         part_start = strchr(p, ':') + 1;
310                         if (!strcmp(part_start, "auto")) {
311                             flag_vals->partnum = -1;
312                         } else {
313                             flag_vals->partnum = strtol(part_start, NULL, 0);
314                         }
315                     } else {
316                         LERROR << "Warning: voldmanaged= flag malformed";
317                     }
318                 } else if ((fl[i].flag == MF_SWAPPRIO) && flag_vals) {
319                     flag_vals->swap_prio = strtoll(strchr(p, '=') + 1, NULL, 0);
320                 } else if ((fl[i].flag == MF_MAX_COMP_STREAMS) && flag_vals) {
321                     flag_vals->max_comp_streams = strtoll(strchr(p, '=') + 1, NULL, 0);
322                 } else if ((fl[i].flag == MF_ZRAMSIZE) && flag_vals) {
323                     int is_percent = !!strrchr(p, '%');
324                     unsigned int val = strtoll(strchr(p, '=') + 1, NULL, 0);
325                     if (is_percent)
326                         flag_vals->zram_size = calculate_zram_size(val);
327                     else
328                         flag_vals->zram_size = val;
329                 } else if ((fl[i].flag == MF_RESERVEDSIZE) && flag_vals) {
330                     /* The reserved flag is followed by an = and the
331                      * reserved size of the partition.  Get it and return it.
332                      */
333                     flag_vals->reserved_size = parse_size(strchr(p, '=') + 1);
334                 } else if ((fl[i].flag == MF_ERASEBLKSIZE) && flag_vals) {
335                     /* The erase block size flag is followed by an = and the flash
336                      * erase block size. Get it, check that it is a power of 2 and
337                      * at least 4096, and return it.
338                      */
339                     unsigned int val = strtoul(strchr(p, '=') + 1, NULL, 0);
340                     if (val >= 4096 && (val & (val - 1)) == 0)
341                         flag_vals->erase_blk_size = val;
342                 } else if ((fl[i].flag == MF_LOGICALBLKSIZE) && flag_vals) {
343                     /* The logical block size flag is followed by an = and the flash
344                      * logical block size. Get it, check that it is a power of 2 and
345                      * at least 4096, and return it.
346                      */
347                     unsigned int val = strtoul(strchr(p, '=') + 1, NULL, 0);
348                     if (val >= 4096 && (val & (val - 1)) == 0)
349                         flag_vals->logical_blk_size = val;
350                 } else if ((fl[i].flag == MF_SYSFS) && flag_vals) {
351                     /* The path to trigger device gc by idle-maint of vold. */
352                     flag_vals->sysfs_path = strdup(strchr(p, '=') + 1);
353                 }
354                 break;
355             }
356         }
357 
358         if (!fl[i].name) {
359             if (fs_options) {
360                 /* It's not a known flag, so it must be a filesystem specific
361                  * option.  Add it to fs_options if it was passed in.
362                  */
363                 strlcat(fs_options, p, fs_options_len);
364                 strlcat(fs_options, ",", fs_options_len);
365             } else {
366                 /* fs_options was not passed in, so if the flag is unknown
367                  * it's an error.
368                  */
369                 LERROR << "Warning: unknown flag " << p;
370             }
371         }
372         p = strtok_r(NULL, ",", &savep);
373     }
374 
375     if (fs_options && fs_options[0]) {
376         /* remove the last trailing comma from the list of options */
377         fs_options[strlen(fs_options) - 1] = '\0';
378     }
379 
380     return f;
381 }
382 
init_android_dt_dir()383 static std::string init_android_dt_dir() {
384     std::string android_dt_dir;
385     // The platform may specify a custom Android DT path in kernel cmdline
386     if (!fs_mgr_get_boot_config_from_kernel_cmdline("android_dt_dir", &android_dt_dir)) {
387         // Fall back to the standard procfs-based path
388         android_dt_dir = kDefaultAndroidDtDir;
389     }
390     return android_dt_dir;
391 }
392 
393 // FIXME: The same logic is duplicated in system/core/init/
get_android_dt_dir()394 const std::string& get_android_dt_dir() {
395     // Set once and saves time for subsequent calls to this function
396     static const std::string kAndroidDtDir = init_android_dt_dir();
397     return kAndroidDtDir;
398 }
399 
is_dt_fstab_compatible()400 static bool is_dt_fstab_compatible() {
401     std::string dt_value;
402     std::string file_name = get_android_dt_dir() + "/fstab/compatible";
403     if (read_dt_file(file_name, &dt_value)) {
404         if (dt_value == "android,fstab") {
405             return true;
406         }
407     }
408 
409     return false;
410 }
411 
read_fstab_from_dt()412 static std::string read_fstab_from_dt() {
413     if (!is_dt_compatible() || !is_dt_fstab_compatible()) {
414         return {};
415     }
416 
417     std::string fstabdir_name = get_android_dt_dir() + "/fstab";
418     std::unique_ptr<DIR, int (*)(DIR*)> fstabdir(opendir(fstabdir_name.c_str()), closedir);
419     if (!fstabdir) return {};
420 
421     dirent* dp;
422     // Each element in fstab_dt_entries is <mount point, the line format in fstab file>.
423     std::vector<std::pair<std::string, std::string>> fstab_dt_entries;
424     while ((dp = readdir(fstabdir.get())) != NULL) {
425         // skip over name, compatible and .
426         if (dp->d_type != DT_DIR || dp->d_name[0] == '.') continue;
427 
428         // create <dev> <mnt_point>  <type>  <mnt_flags>  <fsmgr_flags>\n
429         std::vector<std::string> fstab_entry;
430         std::string file_name;
431         std::string value;
432         // skip a partition entry if the status property is present and not set to ok
433         file_name = android::base::StringPrintf("%s/%s/status", fstabdir_name.c_str(), dp->d_name);
434         if (read_dt_file(file_name, &value)) {
435             if (value != "okay" && value != "ok") {
436                 LINFO << "dt_fstab: Skip disabled entry for partition " << dp->d_name;
437                 continue;
438             }
439         }
440 
441         file_name = android::base::StringPrintf("%s/%s/dev", fstabdir_name.c_str(), dp->d_name);
442         if (!read_dt_file(file_name, &value)) {
443             LERROR << "dt_fstab: Failed to find device for partition " << dp->d_name;
444             return {};
445         }
446         fstab_entry.push_back(value);
447 
448         std::string mount_point;
449         file_name =
450             android::base::StringPrintf("%s/%s/mnt_point", fstabdir_name.c_str(), dp->d_name);
451         if (read_dt_file(file_name, &value)) {
452             LINFO << "dt_fstab: Using a specified mount point " << value << " for " << dp->d_name;
453             mount_point = value;
454         } else {
455             mount_point = android::base::StringPrintf("/%s", dp->d_name);
456         }
457         fstab_entry.push_back(mount_point);
458 
459         file_name = android::base::StringPrintf("%s/%s/type", fstabdir_name.c_str(), dp->d_name);
460         if (!read_dt_file(file_name, &value)) {
461             LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
462             return {};
463         }
464         fstab_entry.push_back(value);
465 
466         file_name = android::base::StringPrintf("%s/%s/mnt_flags", fstabdir_name.c_str(), dp->d_name);
467         if (!read_dt_file(file_name, &value)) {
468             LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
469             return {};
470         }
471         fstab_entry.push_back(value);
472 
473         file_name = android::base::StringPrintf("%s/%s/fsmgr_flags", fstabdir_name.c_str(), dp->d_name);
474         if (!read_dt_file(file_name, &value)) {
475             LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
476             return {};
477         }
478         fstab_entry.push_back(value);
479         // Adds a fstab_entry to fstab_dt_entries, to be sorted by mount_point later.
480         fstab_dt_entries.emplace_back(mount_point, android::base::Join(fstab_entry, " "));
481     }
482 
483     // Sort fstab_dt entries, to ensure /vendor is mounted before /vendor/abc is attempted.
484     std::sort(fstab_dt_entries.begin(), fstab_dt_entries.end(),
485               [](const auto& a, const auto& b) { return a.first < b.first; });
486 
487     std::string fstab_result;
488     for (const auto& [_, dt_entry] : fstab_dt_entries) {
489         fstab_result += dt_entry + "\n";
490     }
491     return fstab_result;
492 }
493 
is_dt_compatible()494 bool is_dt_compatible() {
495     std::string file_name = get_android_dt_dir() + "/compatible";
496     std::string dt_value;
497     if (read_dt_file(file_name, &dt_value)) {
498         if (dt_value == "android,firmware") {
499             return true;
500         }
501     }
502 
503     return false;
504 }
505 
fs_mgr_read_fstab_file(FILE * fstab_file)506 static struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file)
507 {
508     int cnt, entries;
509     ssize_t len;
510     size_t alloc_len = 0;
511     char *line = NULL;
512     const char *delim = " \t";
513     char *save_ptr, *p;
514     struct fstab *fstab = NULL;
515     struct fs_mgr_flag_values flag_vals;
516 #define FS_OPTIONS_LEN 1024
517     char tmp_fs_options[FS_OPTIONS_LEN];
518 
519     entries = 0;
520     while ((len = getline(&line, &alloc_len, fstab_file)) != -1) {
521         /* if the last character is a newline, shorten the string by 1 byte */
522         if (line[len - 1] == '\n') {
523             line[len - 1] = '\0';
524         }
525         /* Skip any leading whitespace */
526         p = line;
527         while (isspace(*p)) {
528             p++;
529         }
530         /* ignore comments or empty lines */
531         if (*p == '#' || *p == '\0')
532             continue;
533         entries++;
534     }
535 
536     if (!entries) {
537         LERROR << "No entries found in fstab";
538         goto err;
539     }
540 
541     /* Allocate and init the fstab structure */
542     fstab = static_cast<struct fstab *>(calloc(1, sizeof(struct fstab)));
543     fstab->num_entries = entries;
544     fstab->recs = static_cast<struct fstab_rec *>(
545         calloc(fstab->num_entries, sizeof(struct fstab_rec)));
546 
547     fseek(fstab_file, 0, SEEK_SET);
548 
549     cnt = 0;
550     while ((len = getline(&line, &alloc_len, fstab_file)) != -1) {
551         /* if the last character is a newline, shorten the string by 1 byte */
552         if (line[len - 1] == '\n') {
553             line[len - 1] = '\0';
554         }
555 
556         /* Skip any leading whitespace */
557         p = line;
558         while (isspace(*p)) {
559             p++;
560         }
561         /* ignore comments or empty lines */
562         if (*p == '#' || *p == '\0')
563             continue;
564 
565         /* If a non-comment entry is greater than the size we allocated, give an
566          * error and quit.  This can happen in the unlikely case the file changes
567          * between the two reads.
568          */
569         if (cnt >= entries) {
570             LERROR << "Tried to process more entries than counted";
571             break;
572         }
573 
574         if (!(p = strtok_r(line, delim, &save_ptr))) {
575             LERROR << "Error parsing mount source";
576             goto err;
577         }
578         fstab->recs[cnt].blk_device = strdup(p);
579 
580         if (!(p = strtok_r(NULL, delim, &save_ptr))) {
581             LERROR << "Error parsing mount_point";
582             goto err;
583         }
584         fstab->recs[cnt].mount_point = strdup(p);
585 
586         if (!(p = strtok_r(NULL, delim, &save_ptr))) {
587             LERROR << "Error parsing fs_type";
588             goto err;
589         }
590         fstab->recs[cnt].fs_type = strdup(p);
591 
592         if (!(p = strtok_r(NULL, delim, &save_ptr))) {
593             LERROR << "Error parsing mount_flags";
594             goto err;
595         }
596         tmp_fs_options[0] = '\0';
597         fstab->recs[cnt].flags = parse_flags(p, mount_flags, NULL,
598                                        tmp_fs_options, FS_OPTIONS_LEN);
599 
600         /* fs_options are optional */
601         if (tmp_fs_options[0]) {
602             fstab->recs[cnt].fs_options = strdup(tmp_fs_options);
603         } else {
604             fstab->recs[cnt].fs_options = NULL;
605         }
606 
607         if (!(p = strtok_r(NULL, delim, &save_ptr))) {
608             LERROR << "Error parsing fs_mgr_options";
609             goto err;
610         }
611         fstab->recs[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags,
612                                                     &flag_vals, NULL, 0);
613         fstab->recs[cnt].key_loc = flag_vals.key_loc;
614         fstab->recs[cnt].key_dir = flag_vals.key_dir;
615         fstab->recs[cnt].verity_loc = flag_vals.verity_loc;
616         fstab->recs[cnt].length = flag_vals.part_length;
617         fstab->recs[cnt].label = flag_vals.label;
618         fstab->recs[cnt].partnum = flag_vals.partnum;
619         fstab->recs[cnt].swap_prio = flag_vals.swap_prio;
620         fstab->recs[cnt].max_comp_streams = flag_vals.max_comp_streams;
621         fstab->recs[cnt].zram_size = flag_vals.zram_size;
622         fstab->recs[cnt].reserved_size = flag_vals.reserved_size;
623         fstab->recs[cnt].file_contents_mode = flag_vals.file_contents_mode;
624         fstab->recs[cnt].file_names_mode = flag_vals.file_names_mode;
625         fstab->recs[cnt].erase_blk_size = flag_vals.erase_blk_size;
626         fstab->recs[cnt].logical_blk_size = flag_vals.logical_blk_size;
627         fstab->recs[cnt].sysfs_path = flag_vals.sysfs_path;
628         cnt++;
629     }
630     /* If an A/B partition, modify block device to be the real block device */
631     if (!fs_mgr_update_for_slotselect(fstab)) {
632         LERROR << "Error updating for slotselect";
633         goto err;
634     }
635     free(line);
636     return fstab;
637 
638 err:
639     free(line);
640     if (fstab)
641         fs_mgr_free_fstab(fstab);
642     return NULL;
643 }
644 
645 /* merges fstab entries from both a and b, then returns the merged result.
646  * note that the caller should only manage the return pointer without
647  * doing further memory management for the two inputs, i.e. only need to
648  * frees up memory of the return value without touching a and b. */
in_place_merge(struct fstab * a,struct fstab * b)649 static struct fstab *in_place_merge(struct fstab *a, struct fstab *b)
650 {
651     if (!a && !b) return nullptr;
652     if (!a) return b;
653     if (!b) return a;
654 
655     int total_entries = a->num_entries + b->num_entries;
656     a->recs = static_cast<struct fstab_rec *>(realloc(
657         a->recs, total_entries * (sizeof(struct fstab_rec))));
658     if (!a->recs) {
659         LERROR << __FUNCTION__ << "(): failed to allocate fstab recs";
660         // If realloc() fails the original block is left untouched;
661         // it is not freed or moved. So we have to free both a and b here.
662         fs_mgr_free_fstab(a);
663         fs_mgr_free_fstab(b);
664         return nullptr;
665     }
666 
667     for (int i = a->num_entries, j = 0; i < total_entries; i++, j++) {
668         // Copy the structs by assignment.
669         a->recs[i] = b->recs[j];
670     }
671 
672     // We can't call fs_mgr_free_fstab because a->recs still references the
673     // memory allocated by strdup.
674     free(b->recs);
675     free(b->fstab_filename);
676     free(b);
677 
678     a->num_entries = total_entries;
679     return a;
680 }
681 
682 /* Extracts <device>s from the by-name symlinks specified in a fstab:
683  *   /dev/block/<type>/<device>/by-name/<partition>
684  *
685  * <type> can be: platform, pci or vbd.
686  *
687  * For example, given the following entries in the input fstab:
688  *   /dev/block/platform/soc/1da4000.ufshc/by-name/system
689  *   /dev/block/pci/soc.0/f9824900.sdhci/by-name/vendor
690  * it returns a set { "soc/1da4000.ufshc", "soc.0/f9824900.sdhci" }.
691  */
extract_boot_devices(const fstab & fstab)692 static std::set<std::string> extract_boot_devices(const fstab& fstab) {
693     std::set<std::string> boot_devices;
694 
695     for (int i = 0; i < fstab.num_entries; i++) {
696         std::string blk_device(fstab.recs[i].blk_device);
697         // Skips blk_device that doesn't conform to the format.
698         if (!android::base::StartsWith(blk_device, "/dev/block") ||
699             android::base::StartsWith(blk_device, "/dev/block/by-name") ||
700             android::base::StartsWith(blk_device, "/dev/block/bootdevice/by-name")) {
701             continue;
702         }
703         // Skips non-by_name blk_device.
704         // /dev/block/<type>/<device>/by-name/<partition>
705         //                           ^ slash_by_name
706         auto slash_by_name = blk_device.find("/by-name");
707         if (slash_by_name == std::string::npos) continue;
708         blk_device.erase(slash_by_name);  // erases /by-name/<partition>
709 
710         // Erases /dev/block/, now we have <type>/<device>
711         blk_device.erase(0, std::string("/dev/block/").size());
712 
713         // <type>/<device>
714         //       ^ first_slash
715         auto first_slash = blk_device.find('/');
716         if (first_slash == std::string::npos) continue;
717 
718         auto boot_device = blk_device.substr(first_slash + 1);
719         if (!boot_device.empty()) boot_devices.insert(std::move(boot_device));
720     }
721 
722     return boot_devices;
723 }
724 
fs_mgr_read_fstab(const char * fstab_path)725 struct fstab *fs_mgr_read_fstab(const char *fstab_path)
726 {
727     FILE *fstab_file;
728     struct fstab *fstab;
729 
730     fstab_file = fopen(fstab_path, "r");
731     if (!fstab_file) {
732         PERROR << __FUNCTION__<< "(): cannot open file: '" << fstab_path << "'";
733         return nullptr;
734     }
735 
736     fstab = fs_mgr_read_fstab_file(fstab_file);
737     if (fstab) {
738         fstab->fstab_filename = strdup(fstab_path);
739     } else {
740         LERROR << __FUNCTION__ << "(): failed to load fstab from : '" << fstab_path << "'";
741     }
742 
743     fclose(fstab_file);
744     return fstab;
745 }
746 
747 /* Returns fstab entries parsed from the device tree if they
748  * exist
749  */
fs_mgr_read_fstab_dt()750 struct fstab *fs_mgr_read_fstab_dt()
751 {
752     std::string fstab_buf = read_fstab_from_dt();
753     if (fstab_buf.empty()) {
754         LINFO << __FUNCTION__ << "(): failed to read fstab from dt";
755         return nullptr;
756     }
757 
758     std::unique_ptr<FILE, decltype(&fclose)> fstab_file(
759         fmemopen(static_cast<void*>(const_cast<char*>(fstab_buf.c_str())),
760                  fstab_buf.length(), "r"), fclose);
761     if (!fstab_file) {
762         PERROR << __FUNCTION__ << "(): failed to create a file stream for fstab dt";
763         return nullptr;
764     }
765 
766     struct fstab *fstab = fs_mgr_read_fstab_file(fstab_file.get());
767     if (!fstab) {
768         LERROR << __FUNCTION__ << "(): failed to load fstab from kernel:"
769                << std::endl << fstab_buf;
770     }
771 
772     return fstab;
773 }
774 
775 /*
776  * Identify path to fstab file. Lookup is based on pattern
777  * fstab.<hardware>, fstab.<hardware.platform> in folders
778    /odm/etc, vendor/etc, or /.
779  */
get_fstab_path()780 static std::string get_fstab_path()
781 {
782     for (const char* prop : {"hardware", "hardware.platform"}) {
783         std::string hw;
784 
785         if (!fs_mgr_get_boot_config(prop, &hw)) continue;
786 
787         for (const char* prefix : {"/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab."}) {
788             std::string fstab_path = prefix + hw;
789             if (access(fstab_path.c_str(), F_OK) == 0) {
790                 return fstab_path;
791             }
792         }
793     }
794 
795     return std::string();
796 }
797 
798 /*
799  * loads the fstab file and combines with fstab entries passed in from device tree.
800  */
fs_mgr_read_fstab_default()801 struct fstab *fs_mgr_read_fstab_default()
802 {
803     std::string default_fstab;
804 
805     // Use different fstab paths for normal boot and recovery boot, respectively
806     if (access("/sbin/recovery", F_OK) == 0) {
807         default_fstab = "/etc/recovery.fstab";
808     } else {  // normal boot
809         default_fstab = get_fstab_path();
810     }
811 
812     struct fstab* fstab = nullptr;
813     if (!default_fstab.empty()) {
814         fstab = fs_mgr_read_fstab(default_fstab.c_str());
815     } else {
816         LINFO << __FUNCTION__ << "(): failed to find device default fstab";
817     }
818 
819     struct fstab* fstab_dt = fs_mgr_read_fstab_dt();
820 
821     // combines fstab entries passed in from device tree with
822     // the ones found from default_fstab file
823     return in_place_merge(fstab_dt, fstab);
824 }
825 
fs_mgr_free_fstab(struct fstab * fstab)826 void fs_mgr_free_fstab(struct fstab *fstab)
827 {
828     int i;
829 
830     if (!fstab) {
831         return;
832     }
833 
834     for (i = 0; i < fstab->num_entries; i++) {
835         /* Free the pointers return by strdup(3) */
836         free(fstab->recs[i].blk_device);
837         free(fstab->recs[i].mount_point);
838         free(fstab->recs[i].fs_type);
839         free(fstab->recs[i].fs_options);
840         free(fstab->recs[i].key_loc);
841         free(fstab->recs[i].key_dir);
842         free(fstab->recs[i].label);
843         free(fstab->recs[i].sysfs_path);
844     }
845 
846     /* Free the fstab_recs array created by calloc(3) */
847     free(fstab->recs);
848 
849     /* Free the fstab filename */
850     free(fstab->fstab_filename);
851 
852     /* Free fstab */
853     free(fstab);
854 }
855 
856 /* Add an entry to the fstab, and return 0 on success or -1 on error */
fs_mgr_add_entry(struct fstab * fstab,const char * mount_point,const char * fs_type,const char * blk_device)857 int fs_mgr_add_entry(struct fstab *fstab,
858                      const char *mount_point, const char *fs_type,
859                      const char *blk_device)
860 {
861     struct fstab_rec *new_fstab_recs;
862     int n = fstab->num_entries;
863 
864     new_fstab_recs = (struct fstab_rec *)
865                      realloc(fstab->recs, sizeof(struct fstab_rec) * (n + 1));
866 
867     if (!new_fstab_recs) {
868         return -1;
869     }
870 
871     /* A new entry was added, so initialize it */
872      memset(&new_fstab_recs[n], 0, sizeof(struct fstab_rec));
873      new_fstab_recs[n].mount_point = strdup(mount_point);
874      new_fstab_recs[n].fs_type = strdup(fs_type);
875      new_fstab_recs[n].blk_device = strdup(blk_device);
876      new_fstab_recs[n].length = 0;
877 
878      /* Update the fstab struct */
879      fstab->recs = new_fstab_recs;
880      fstab->num_entries++;
881 
882      return 0;
883 }
884 
885 /*
886  * Returns the fstab_rec* whose mount_point is path.
887  * Returns nullptr if not found.
888  */
fs_mgr_get_entry_for_mount_point(struct fstab * fstab,const std::string & path)889 struct fstab_rec* fs_mgr_get_entry_for_mount_point(struct fstab* fstab, const std::string& path) {
890     if (!fstab) {
891         return nullptr;
892     }
893     for (int i = 0; i < fstab->num_entries; i++) {
894         if (fstab->recs[i].mount_point && path == fstab->recs[i].mount_point) {
895             return &fstab->recs[i];
896         }
897     }
898     return nullptr;
899 }
900 
fs_mgr_get_boot_devices()901 std::set<std::string> fs_mgr_get_boot_devices() {
902     // boot_devices can be specified in device tree.
903     std::string dt_value;
904     std::string file_name = get_android_dt_dir() + "/boot_devices";
905     if (read_dt_file(file_name, &dt_value)) {
906         auto boot_devices = android::base::Split(dt_value, ",");
907         return std::set<std::string>(boot_devices.begin(), boot_devices.end());
908     }
909 
910     // Fallback to extract boot devices from fstab.
911     std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
912                                                                fs_mgr_free_fstab);
913     if (fstab) return extract_boot_devices(*fstab);
914 
915     return {};
916 }
917 
fs_mgr_is_voldmanaged(const struct fstab_rec * fstab)918 int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab)
919 {
920     return fstab->fs_mgr_flags & MF_VOLDMANAGED;
921 }
922 
fs_mgr_is_nonremovable(const struct fstab_rec * fstab)923 int fs_mgr_is_nonremovable(const struct fstab_rec *fstab)
924 {
925     return fstab->fs_mgr_flags & MF_NONREMOVABLE;
926 }
927 
fs_mgr_is_verified(const struct fstab_rec * fstab)928 int fs_mgr_is_verified(const struct fstab_rec *fstab)
929 {
930     return fstab->fs_mgr_flags & MF_VERIFY;
931 }
932 
fs_mgr_is_avb(const struct fstab_rec * fstab)933 int fs_mgr_is_avb(const struct fstab_rec *fstab)
934 {
935     return fstab->fs_mgr_flags & MF_AVB;
936 }
937 
fs_mgr_is_verifyatboot(const struct fstab_rec * fstab)938 int fs_mgr_is_verifyatboot(const struct fstab_rec *fstab)
939 {
940     return fstab->fs_mgr_flags & MF_VERIFYATBOOT;
941 }
942 
fs_mgr_is_encryptable(const struct fstab_rec * fstab)943 int fs_mgr_is_encryptable(const struct fstab_rec *fstab)
944 {
945     return fstab->fs_mgr_flags & (MF_CRYPT | MF_FORCECRYPT | MF_FORCEFDEORFBE);
946 }
947 
fs_mgr_is_file_encrypted(const struct fstab_rec * fstab)948 int fs_mgr_is_file_encrypted(const struct fstab_rec *fstab)
949 {
950     return fstab->fs_mgr_flags & MF_FILEENCRYPTION;
951 }
952 
fs_mgr_get_file_encryption_modes(const struct fstab_rec * fstab,const char ** contents_mode_ret,const char ** filenames_mode_ret)953 void fs_mgr_get_file_encryption_modes(const struct fstab_rec *fstab,
954                                       const char **contents_mode_ret,
955                                       const char **filenames_mode_ret)
956 {
957     *contents_mode_ret = flag_to_encryption_mode(file_contents_encryption_modes,
958                                                  fstab->file_contents_mode);
959     *filenames_mode_ret = flag_to_encryption_mode(file_names_encryption_modes,
960                                                   fstab->file_names_mode);
961 }
962 
fs_mgr_is_convertible_to_fbe(const struct fstab_rec * fstab)963 int fs_mgr_is_convertible_to_fbe(const struct fstab_rec *fstab)
964 {
965     return fstab->fs_mgr_flags & MF_FORCEFDEORFBE;
966 }
967 
fs_mgr_is_noemulatedsd(const struct fstab_rec * fstab)968 int fs_mgr_is_noemulatedsd(const struct fstab_rec *fstab)
969 {
970     return fstab->fs_mgr_flags & MF_NOEMULATEDSD;
971 }
972 
fs_mgr_is_notrim(const struct fstab_rec * fstab)973 int fs_mgr_is_notrim(const struct fstab_rec* fstab) {
974     return fstab->fs_mgr_flags & MF_NOTRIM;
975 }
976 
fs_mgr_is_formattable(const struct fstab_rec * fstab)977 int fs_mgr_is_formattable(const struct fstab_rec* fstab) {
978     return fstab->fs_mgr_flags & (MF_FORMATTABLE);
979 }
980 
fs_mgr_is_slotselect(const struct fstab_rec * fstab)981 int fs_mgr_is_slotselect(const struct fstab_rec* fstab) {
982     return fstab->fs_mgr_flags & MF_SLOTSELECT;
983 }
984 
fs_mgr_is_nofail(const struct fstab_rec * fstab)985 int fs_mgr_is_nofail(const struct fstab_rec* fstab) {
986     return fstab->fs_mgr_flags & MF_NOFAIL;
987 }
988 
fs_mgr_is_latemount(const struct fstab_rec * fstab)989 int fs_mgr_is_latemount(const struct fstab_rec* fstab) {
990     return fstab->fs_mgr_flags & MF_LATEMOUNT;
991 }
992 
fs_mgr_is_quota(const struct fstab_rec * fstab)993 int fs_mgr_is_quota(const struct fstab_rec* fstab) {
994     return fstab->fs_mgr_flags & MF_QUOTA;
995 }
996 
fs_mgr_has_sysfs_path(const struct fstab_rec * fstab)997 int fs_mgr_has_sysfs_path(const struct fstab_rec *fstab)
998 {
999     return fstab->fs_mgr_flags & MF_SYSFS;
1000 }
1001