fs_mgr.c revision c1bf89663ca71949b508007d4df2b5b06038f96d
1c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* 2c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * Copyright (C) 2012 The Android Open Source Project 3c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * 4c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * Licensed under the Apache License, Version 2.0 (the "License"); 5c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * you may not use this file except in compliance with the License. 6c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * You may obtain a copy of the License at 7c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * 8c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * http://www.apache.org/licenses/LICENSE-2.0 9c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * 10c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * Unless required by applicable law or agreed to in writing, software 11c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * distributed under the License is distributed on an "AS IS" BASIS, 12c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * See the License for the specific language governing permissions and 14c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * limitations under the License. 15c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 16c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 17c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* TO DO: 18c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * 1. Re-direct fsck output to the kernel log? 19c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * 20c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 21c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 22c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <stdio.h> 23c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <stdlib.h> 24c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <string.h> 25c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <unistd.h> 26c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <fcntl.h> 27c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <ctype.h> 28c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <sys/mount.h> 29c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <sys/stat.h> 30c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <errno.h> 31c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <sys/types.h> 32c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <sys/wait.h> 33c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <libgen.h> 34c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <time.h> 35c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 36c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <private/android_filesystem_config.h> 37c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <cutils/partition_utils.h> 38c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include <cutils/properties.h> 39c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 40c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#include "fs_mgr_priv.h" 41c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 42c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#define KEY_LOC_PROP "ro.crypto.keyfile.userdata" 43c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#define KEY_IN_FOOTER "footer" 44c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 45c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#define E2FSCK_BIN "/system/bin/e2fsck" 46c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 47c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstruct flag_list { 48c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall const char *name; 49c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall unsigned flag; 50c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}; 51c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 52c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic struct flag_list mount_flags[] = { 53c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "noatime", MS_NOATIME }, 54c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "noexec", MS_NOEXEC }, 55c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "nosuid", MS_NOSUID }, 56c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "nodev", MS_NODEV }, 57c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "nodiratime", MS_NODIRATIME }, 58c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "ro", MS_RDONLY }, 59c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "rw", 0 }, 60c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "remount", MS_REMOUNT }, 61c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "defaults", 0 }, 62c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { 0, 0 }, 63c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}; 64c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 65c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic struct flag_list fs_mgr_flags[] = { 66c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "wait", MF_WAIT }, 67c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "check", MF_CHECK }, 68c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "encryptable=",MF_CRYPT }, 69c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { "defaults", 0 }, 70c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall { 0, 0 }, 71c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall}; 72c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 73c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* 74c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * gettime() - returns the time in seconds of the system's monotonic clock or 75c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * zero on error. 76c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 77c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic time_t gettime(void) 78c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 79c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct timespec ts; 80c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret; 81c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 82c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = clock_gettime(CLOCK_MONOTONIC, &ts); 83c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (ret < 0) { 84c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno)); 85c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 86c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 87c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 88c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ts.tv_sec; 89c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 90c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 91c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic int wait_for_file(const char *filename, int timeout) 92c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 93c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct stat info; 94c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall time_t timeout_time = gettime() + timeout; 95c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret = -1; 96c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 97c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0)) 98c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall usleep(10000); 99c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 100c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 101c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 102c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 103c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic int parse_flags(char *flags, struct flag_list *fl, char **key_loc, 104c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *fs_options, int fs_options_len) 105c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 106c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int f = 0; 107c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int i; 108c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *p; 109c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *savep; 110c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 111c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* initialize key_loc to null, if we find an MF_CRYPT flag, 112c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * then we'll set key_loc to the proper value */ 113c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (key_loc) { 114c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *key_loc = NULL; 115c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 116c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* initialize fs_options to the null string */ 117c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fs_options && (fs_options_len > 0)) { 118c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fs_options[0] = '\0'; 119c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 120c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 121c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall p = strtok_r(flags, ",", &savep); 122c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (p) { 123c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Look for the flag "p" in the flag list "fl" 124c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * If not found, the loop exits with fl[i].name being null. 125c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 126c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall for (i = 0; fl[i].name; i++) { 127c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!strncmp(p, fl[i].name, strlen(fl[i].name))) { 128c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall f |= fl[i].flag; 129c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if ((fl[i].flag == MF_CRYPT) && key_loc) { 130c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* The encryptable flag is followed by an = and the 131c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * location of the keys. Get it and return it. 132c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 133c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *key_loc = strdup(strchr(p, '=') + 1); 134c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 135c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall break; 136c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 137c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 138c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 139c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!fl[i].name) { 140c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fs_options) { 141c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* It's not a known flag, so it must be a filesystem specific 142c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * option. Add it to fs_options if it was passed in. 143c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 144c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall strlcat(fs_options, p, fs_options_len); 145c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall strlcat(fs_options, ",", fs_options_len); 146c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 147c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* fs_options was not passed in, so if the flag is unknown 148c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * it's an error. 149c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 150c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Warning: unknown flag %s\n", p); 151c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 152c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 153c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall p = strtok_r(NULL, ",", &savep); 154c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 155c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 156c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallout: 157c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fs_options && fs_options[0]) { 158c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* remove the last trailing comma from the list of options */ 159c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fs_options[strlen(fs_options) - 1] = '\0'; 160c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 161c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 162c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return f; 163c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 164c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 165c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* Read a line of text till the next newline character. 166c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * If no newline is found before the buffer is full, continue reading till a new line is seen, 167c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * then return an empty buffer. This effectively ignores lines that are too long. 168c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * On EOF, return null. 169c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 170c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic char *getline(char *buf, int size, FILE *file) 171c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 172c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int cnt = 0; 173c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int eof = 0; 174c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int eol = 0; 175c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int c; 176c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 177c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (size < 1) { 178c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return NULL; 179c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 180c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 181c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (cnt < (size - 1)) { 182c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall c = getc(file); 183c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (c == EOF) { 184c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall eof = 1; 185c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall break; 186c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 187c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 188c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *(buf + cnt) = c; 189c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall cnt++; 190c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 191c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (c == '\n') { 192c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall eol = 1; 193c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall break; 194c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 195c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 196c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 197c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Null terminate what we've read */ 198c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *(buf + cnt) = '\0'; 199c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 200c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (eof) { 201c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (cnt) { 202c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return buf; 203c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 204c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return NULL; 205c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 206c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else if (eol) { 207c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return buf; 208c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 209c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* The line is too long. Read till a newline or EOF. 210c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * If EOF, return null, if newline, return an empty buffer. 211c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 212c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while(1) { 213c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall c = getc(file); 214c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (c == EOF) { 215c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return NULL; 216c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else if (c == '\n') { 217c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *buf = '\0'; 218c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return buf; 219c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 220c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 221c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 222c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 223c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 224c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic struct fstab_rec *read_fstab(char *fstab_path) 225c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 226c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall FILE *fstab_file; 227c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int cnt, entries; 228c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int len; 229c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char line[256]; 230c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall const char *delim = " \t"; 231c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *save_ptr, *p; 232c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct fstab_rec *fstab; 233c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *key_loc; 234c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall#define FS_OPTIONS_LEN 1024 235c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char tmp_fs_options[FS_OPTIONS_LEN]; 236c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 237c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab_file = fopen(fstab_path, "r"); 238c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!fstab_file) { 239c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot open file %s\n", fstab_path); 240c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 241c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 242c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 243c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall entries = 0; 244c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (getline(line, sizeof(line), fstab_file)) { 245c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* if the last character is a newline, shorten the string by 1 byte */ 246c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall len = strlen(line); 247c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (line[len - 1] == '\n') { 248c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall line[len - 1] = '\0'; 249c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 250c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Skip any leading whitespace */ 251c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall p = line; 252c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (isspace(*p)) { 253c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall p++; 254c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 255c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* ignore comments or empty lines */ 256c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (*p == '#' || *p == '\0') 257c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall continue; 258c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall entries++; 259c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 260c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 261c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!entries) { 262c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("No entries found in fstab\n"); 263c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 264c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 265c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 266c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab = calloc(entries + 1, sizeof(struct fstab_rec)); 267c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 268c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fseek(fstab_file, 0, SEEK_SET); 269c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 270c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall cnt = 0; 271c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (getline(line, sizeof(line), fstab_file)) { 272c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* if the last character is a newline, shorten the string by 1 byte */ 273c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall len = strlen(line); 274c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (line[len - 1] == '\n') { 275c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall line[len - 1] = '\0'; 276c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 277c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 278c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Skip any leading whitespace */ 279c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall p = line; 280c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (isspace(*p)) { 281c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall p++; 282c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 283c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* ignore comments or empty lines */ 284c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (*p == '#' || *p == '\0') 285c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall continue; 286c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 287c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* If a non-comment entry is greater than the size we allocated, give an 288c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * error and quit. This can happen in the unlikely case the file changes 289c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * between the two reads. 290c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 291c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (cnt >= entries) { 292c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Tried to process more entries than counted\n"); 293c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall break; 294c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 295c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 296c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(p = strtok_r(line, delim, &save_ptr))) { 297c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Error parsing mount source\n"); 298c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 299c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 300c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].blk_dev = strdup(p); 301c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 302c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(p = strtok_r(NULL, delim, &save_ptr))) { 303c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Error parsing mnt_point\n"); 304c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 305c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 306c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].mnt_point = strdup(p); 307c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 308c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(p = strtok_r(NULL, delim, &save_ptr))) { 309c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Error parsing fs_type\n"); 310c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 311c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 312c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].type = strdup(p); 313c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 314c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(p = strtok_r(NULL, delim, &save_ptr))) { 315c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Error parsing mount_flags\n"); 316c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 317c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 318c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall tmp_fs_options[0] = '\0'; 319c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].flags = parse_flags(p, mount_flags, 0, tmp_fs_options, FS_OPTIONS_LEN); 320c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 321c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* fs_options are optional */ 322c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (tmp_fs_options[0]) { 323c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].fs_options = strdup(tmp_fs_options); 324c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 325c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].fs_options = NULL; 326c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 327c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 328c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(p = strtok_r(NULL, delim, &save_ptr))) { 329c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Error parsing fs_mgr_options\n"); 330c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 331c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 332c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags, &key_loc, 0, 0); 333c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[cnt].key_loc = key_loc; 334c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 335c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall cnt++; 336c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 337c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fclose(fstab_file); 338c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 339c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return fstab; 340c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 341c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 342c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic void free_fstab(struct fstab_rec *fstab) 343c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 344c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int i = 0; 345c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 346c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (fstab[i].blk_dev) { 347c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Free the pointers return by strdup(3) */ 348c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(fstab[i].blk_dev); 349c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(fstab[i].mnt_point); 350c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(fstab[i].type); 351c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(fstab[i].fs_options); 352c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(fstab[i].key_loc); 353c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 354c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall i++; 355c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 356c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 357c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Free the actual fstab array created by calloc(3) */ 358c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(fstab); 359c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 360c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 361c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic void check_fs(char *blk_dev, char *type) 362c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 363c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall pid_t pid; 364c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int status; 365c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 366c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Check for the types of filesystems we know how to check */ 367c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!strcmp(type, "ext2") || !strcmp(type, "ext3") || !strcmp(type, "ext4")) { 368c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall INFO("Running %s on %s\n", E2FSCK_BIN, blk_dev); 369c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall pid = fork(); 370c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (pid > 0) { 371c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Parent, wait for the child to return */ 372c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall waitpid(pid, &status, 0); 373c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else if (pid == 0) { 374c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* child, run checker */ 375c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall execlp(E2FSCK_BIN, E2FSCK_BIN, "-y", blk_dev, (char *)NULL); 376c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 377c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Only gets here on error */ 378c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot run fs_mgr binary %s\n", E2FSCK_BIN); 379c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 380c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* No need to check for error in fork, we can't really handle it now */ 381c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Fork failed trying to run %s\n", E2FSCK_BIN); 382c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 383c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 384c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 385c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return; 386c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 387c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 388c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic void remove_trailing_slashes(char *n) 389c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 390c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int len; 391c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 392c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall len = strlen(n) - 1; 393c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while ((*(n + len) == '/') && len) { 394c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *(n + len) = '\0'; 395c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall len--; 396c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 397c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 398c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 399c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallstatic int fs_match(char *in1, char *in2) 400c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 401c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *n1; 402c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *n2; 403c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret; 404c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 405c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall n1 = strdup(in1); 406c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall n2 = strdup(in2); 407c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 408c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall remove_trailing_slashes(n1); 409c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall remove_trailing_slashes(n2); 410c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 411c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = !strcmp(n1, n2); 412c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 413c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(n1); 414c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free(n2); 415c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 416c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 417c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 418c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 419c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_mount_all(char *fstab_file) 420c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 421c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int i = 0; 422c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int encrypted = 0; 423c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret = -1; 424c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int mret; 425c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct fstab_rec *fstab = 0; 426c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 427c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(fstab = read_fstab(fstab_file))) { 428c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 429c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 430c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 431c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall for (i = 0; fstab[i].blk_dev; i++) { 432c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fstab[i].fs_mgr_flags & MF_WAIT) { 433c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall wait_for_file(fstab[i].blk_dev, WAIT_TIMEOUT); 434c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 435c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 436c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fstab[i].fs_mgr_flags & MF_CHECK) { 437c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall check_fs(fstab[i].blk_dev, fstab[i].type); 438c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 439c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 440c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall mret = mount(fstab[i].blk_dev, fstab[i].mnt_point, fstab[i].type, 441c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[i].flags, fstab[i].fs_options); 442c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!mret) { 443c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Success! Go get the next one */ 444c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall continue; 445c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 446c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 447c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* mount(2) returned an error, check if it's encrypted and deal with it */ 448c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if ((fstab[i].fs_mgr_flags & MF_CRYPT) && !partition_wiped(fstab[i].blk_dev)) { 449c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Need to mount a tmpfs at this mountpoint for now, and set 450c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * properties that vold will query later for decrypting 451c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 452c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (mount("tmpfs", fstab[i].mnt_point, "tmpfs", 453c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS) < 0) { 454c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot mount tmpfs filesystem for encrypted fs at %s\n", 455c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[i].mnt_point); 456c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall goto out; 457c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 458c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall encrypted = 1; 459c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 460c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot mount filesystem on %s at %s\n", 461c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[i].blk_dev, fstab[i].mnt_point); 462c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall goto out; 463c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 464c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 465c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 466c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (encrypted) { 467c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = 1; 468c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 469c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = 0; 470c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 471c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 472c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallout: 473c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free_fstab(fstab); 474c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 475c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 476c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 477c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* If tmp_mnt_point is non-null, mount the filesystem there. This is for the 478c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * tmp mount we do to check the user password 479c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 480c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_do_mount(char *fstab_file, char *n_name, char *n_blk_dev, char *tmp_mnt_point) 481c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 482c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int i = 0; 483c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret = -1; 484c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct fstab_rec *fstab = 0; 485c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall char *m; 486c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 487c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(fstab = read_fstab(fstab_file))) { 488c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 489c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 490c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 491c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall for (i = 0; fstab[i].blk_dev; i++) { 492c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!fs_match(fstab[i].mnt_point, n_name)) { 493c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall continue; 494c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 495c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 496c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* We found our match */ 497c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* First check the filesystem if requested */ 498c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fstab[i].fs_mgr_flags & MF_WAIT) { 499c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall wait_for_file(fstab[i].blk_dev, WAIT_TIMEOUT); 500c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 501c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 502c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (fstab[i].fs_mgr_flags & MF_CHECK) { 503c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall check_fs(fstab[i].blk_dev, fstab[i].type); 504c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 505c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 506c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Now mount it where requested */ 507c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (tmp_mnt_point) { 508c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall m = tmp_mnt_point; 509c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 510c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall m = fstab[i].mnt_point; 511c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 512c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (mount(n_blk_dev, m, fstab[i].type, 513c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall fstab[i].flags, fstab[i].fs_options)) { 514c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot mount filesystem on %s at %s\n", 515c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall n_blk_dev, m); 516c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall goto out; 517c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } else { 518c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = 0; 519c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall goto out; 520c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 521c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 522c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 523c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* We didn't find a match, say so and return an error */ 524c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot find mount point %s in fstab\n", fstab[i].mnt_point); 525c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 526c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallout: 527c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free_fstab(fstab); 528c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 529c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 530c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 531c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* 532c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * mount a tmpfs filesystem at the given point. 533c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * return 0 on success, non-zero on failure. 534c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 535c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_do_tmpfs_mount(char *n_name) 536c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 537c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret; 538c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 539c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = mount("tmpfs", n_name, "tmpfs", 540c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS); 541c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (ret < 0) { 542c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot mount tmpfs filesystem at %s\n", n_name); 543c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return -1; 544c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 545c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 546c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Success */ 547c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 548c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 549c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 550c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_unmount_all(char *fstab_file) 551c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 552c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int i = 0; 553c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int ret = 0; 554c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct fstab_rec *fstab = 0; 555c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 556c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(fstab = read_fstab(fstab_file))) { 557c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return -1; 558c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 559c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 560c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall while (fstab[i].blk_dev) { 561c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (umount(fstab[i].mnt_point)) { 562c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ERROR("Cannot unmount filesystem at %s\n", fstab[i].mnt_point); 563c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall ret = -1; 564c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 565c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall i++; 566c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 567c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 568c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free_fstab(fstab); 569c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return ret; 570c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 571c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall/* 572c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * key_loc must be at least PROPERTY_VALUE_MAX bytes long 573c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * 574c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall * real_blk_dev must be at least PROPERTY_VALUE_MAX bytes long 575c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall */ 576c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrallint fs_mgr_get_crypt_info(char *fstab_file, char *key_loc, char *real_blk_dev, int size) 577c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall{ 578c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall int i = 0; 579c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall struct fstab_rec *fstab = 0; 580c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 581c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(fstab = read_fstab(fstab_file))) { 582c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return -1; 583c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 584c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Initialize return values to null strings */ 585c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (key_loc) { 586c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *key_loc = '\0'; 587c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 588c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (real_blk_dev) { 589c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall *real_blk_dev = '\0'; 590c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 591c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 592c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* Look for the encryptable partition to find the data */ 593c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall for (i = 0; fstab[i].blk_dev; i++) { 594c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (!(fstab[i].fs_mgr_flags & MF_CRYPT)) { 595c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall continue; 596c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 597c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 598c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall /* We found a match */ 599c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (key_loc) { 600c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall strlcpy(key_loc, fstab[i].key_loc, size); 601c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 602c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall if (real_blk_dev) { 603c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall strlcpy(real_blk_dev, fstab[i].blk_dev, size); 604c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 605c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall break; 606c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall } 607c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 608c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall free_fstab(fstab); 609c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall return 0; 610c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall} 611c1bf89663ca71949b508007d4df2b5b06038f96dKen Sumrall 612