blob: c91033a94d853c20aa8cffc6180564cad0abb49c [file] [log] [blame]
Ken Sumrallc1bf8962012-01-06 19:09:42 -08001/*
2 * Copyright (C) 2012 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
Ken Sumrallc1bf8962012-01-06 19:09:42 -080017#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <unistd.h>
21#include <fcntl.h>
22#include <ctype.h>
23#include <sys/mount.h>
24#include <sys/stat.h>
25#include <errno.h>
26#include <sys/types.h>
27#include <sys/wait.h>
28#include <libgen.h>
29#include <time.h>
Ken Sumrall5bc31a22013-07-08 19:11:55 -070030#include <sys/swap.h>
Ken Sumrallc1bf8962012-01-06 19:09:42 -080031
Geremy Condra3ad3d1c2013-02-22 18:11:41 -080032#include <linux/loop.h>
Ken Sumrallc1bf8962012-01-06 19:09:42 -080033#include <private/android_filesystem_config.h>
34#include <cutils/partition_utils.h>
35#include <cutils/properties.h>
Ken Sumrallbf021b42013-03-19 19:38:44 -070036#include <logwrap/logwrap.h>
Ken Sumrallc1bf8962012-01-06 19:09:42 -080037
Geremy Condra3ad3d1c2013-02-22 18:11:41 -080038#include "mincrypt/rsa.h"
39#include "mincrypt/sha.h"
40#include "mincrypt/sha256.h"
41
Ken Sumrallc1bf8962012-01-06 19:09:42 -080042#include "fs_mgr_priv.h"
Geremy Condra3ad3d1c2013-02-22 18:11:41 -080043#include "fs_mgr_priv_verity.h"
Ken Sumrallc1bf8962012-01-06 19:09:42 -080044
45#define KEY_LOC_PROP "ro.crypto.keyfile.userdata"
46#define KEY_IN_FOOTER "footer"
47
48#define E2FSCK_BIN "/system/bin/e2fsck"
Ken Sumrall5bc31a22013-07-08 19:11:55 -070049#define MKSWAP_BIN "/system/bin/mkswap"
50
Ken Sumrall4eaf9052013-09-18 17:49:21 -070051#define FSCK_LOG_FILE "/dev/fscklogs/log"
52
Ken Sumrall5bc31a22013-07-08 19:11:55 -070053#define ZRAM_CONF_DEV "/sys/block/zram0/disksize"
Ken Sumrallc1bf8962012-01-06 19:09:42 -080054
Ken Sumrallbf021b42013-03-19 19:38:44 -070055#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
56
Paul Lawrence166fa3d2014-02-03 13:27:49 -080057/**
58 * TODO - Remove to enable always on encryption for all devices
59 * This limits the machines on which this feature is enabled
60 * Remove call from fs_mgr_mount_all as well
61 */
62static const char* serial_numbers[] = {
63 "039b83b8437e9637",
64 0
65};
66
67static int serial_matches()
68{
69 char tmp[PROP_VALUE_MAX];
70 *tmp = 0;
71 __system_property_get("ro.serialno", tmp);
72
73 const char** i;
74 for (i = serial_numbers; *i; ++i) {
75 if (!strcmp(*i, tmp)) {
76 return 1;
77 }
78 }
79
80 return 0;
81}
82
Ken Sumrallc1bf8962012-01-06 19:09:42 -080083/*
84 * gettime() - returns the time in seconds of the system's monotonic clock or
85 * zero on error.
86 */
87static time_t gettime(void)
88{
89 struct timespec ts;
90 int ret;
91
92 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
93 if (ret < 0) {
94 ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno));
95 return 0;
96 }
97
98 return ts.tv_sec;
99}
100
101static int wait_for_file(const char *filename, int timeout)
102{
103 struct stat info;
104 time_t timeout_time = gettime() + timeout;
105 int ret = -1;
106
107 while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0))
108 usleep(10000);
109
110 return ret;
111}
112
Ken Sumrallab6b8522013-02-13 12:58:40 -0800113static void check_fs(char *blk_device, char *fs_type, char *target)
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800114{
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800115 int status;
Ken Sumrall5dc5bfe2012-07-23 19:34:00 -0700116 int ret;
117 long tmpmnt_flags = MS_NOATIME | MS_NOEXEC | MS_NOSUID;
118 char *tmpmnt_opts = "nomblk_io_submit,errors=remount-ro";
Ken Sumrallbf021b42013-03-19 19:38:44 -0700119 char *e2fsck_argv[] = {
120 E2FSCK_BIN,
121 "-y",
122 blk_device
123 };
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800124
125 /* Check for the types of filesystems we know how to check */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800126 if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) {
Ken Sumrall5dc5bfe2012-07-23 19:34:00 -0700127 /*
128 * First try to mount and unmount the filesystem. We do this because
129 * the kernel is more efficient than e2fsck in running the journal and
130 * processing orphaned inodes, and on at least one device with a
131 * performance issue in the emmc firmware, it can take e2fsck 2.5 minutes
132 * to do what the kernel does in about a second.
133 *
134 * After mounting and unmounting the filesystem, run e2fsck, and if an
135 * error is recorded in the filesystem superblock, e2fsck will do a full
136 * check. Otherwise, it does nothing. If the kernel cannot mount the
137 * filesytsem due to an error, e2fsck is still run to do a full check
138 * fix the filesystem.
139 */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800140 ret = mount(blk_device, target, fs_type, tmpmnt_flags, tmpmnt_opts);
141 if (!ret) {
Ken Sumrall5dc5bfe2012-07-23 19:34:00 -0700142 umount(target);
143 }
144
David 'Digit' Turner28483d72014-02-17 11:14:44 +0100145 /*
146 * Some system images do not have e2fsck for licensing reasons
147 * (e.g. recent SDK system images). Detect these and skip the check.
148 */
149 if (access(E2FSCK_BIN, X_OK)) {
150 INFO("Not running %s on %s (executable not in system image)\n",
151 E2FSCK_BIN, blk_device);
152 } else {
153 INFO("Running %s on %s\n", E2FSCK_BIN, blk_device);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800154
David 'Digit' Turner28483d72014-02-17 11:14:44 +0100155 ret = android_fork_execvp_ext(ARRAY_SIZE(e2fsck_argv), e2fsck_argv,
156 &status, true, LOG_KLOG | LOG_FILE,
157 true, FSCK_LOG_FILE);
Ken Sumrallbf021b42013-03-19 19:38:44 -0700158
David 'Digit' Turner28483d72014-02-17 11:14:44 +0100159 if (ret < 0) {
160 /* No need to check for error in fork, we can't really handle it now */
161 ERROR("Failed trying to run %s\n", E2FSCK_BIN);
162 }
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800163 }
164 }
165
166 return;
167}
168
169static void remove_trailing_slashes(char *n)
170{
171 int len;
172
173 len = strlen(n) - 1;
174 while ((*(n + len) == '/') && len) {
175 *(n + len) = '\0';
176 len--;
177 }
178}
179
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700180/*
181 * Mark the given block device as read-only, using the BLKROSET ioctl.
182 * Return 0 on success, and -1 on error.
183 */
184static void fs_set_blk_ro(const char *blockdev)
185{
186 int fd;
187 int ON = 1;
188
189 fd = open(blockdev, O_RDONLY);
190 if (fd < 0) {
191 // should never happen
192 return;
193 }
194
195 ioctl(fd, BLKROSET, &ON);
196 close(fd);
197}
198
199/*
200 * __mount(): wrapper around the mount() system call which also
201 * sets the underlying block device to read-only if the mount is read-only.
202 * See "man 2 mount" for return values.
203 */
204static int __mount(const char *source, const char *target,
205 const char *filesystemtype, unsigned long mountflags,
206 const void *data)
207{
208 int ret = mount(source, target, filesystemtype, mountflags, data);
209
210 if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
211 fs_set_blk_ro(source);
212 }
213
214 return ret;
215}
216
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800217static int fs_match(char *in1, char *in2)
218{
219 char *n1;
220 char *n2;
221 int ret;
222
223 n1 = strdup(in1);
224 n2 = strdup(in2);
225
226 remove_trailing_slashes(n1);
227 remove_trailing_slashes(n2);
228
229 ret = !strcmp(n1, n2);
230
231 free(n1);
232 free(n2);
233
234 return ret;
235}
236
Geremy Condracd642fc2014-04-02 13:42:06 -0700237static int device_is_debuggable() {
238 int ret = -1;
239 char value[PROP_VALUE_MAX];
240 ret = __system_property_get("ro.debuggable", value);
241 if (ret < 0)
242 return ret;
243 return strcmp(value, "1") ? 0 : 1;
244}
245
Ken Sumrallab6b8522013-02-13 12:58:40 -0800246int fs_mgr_mount_all(struct fstab *fstab)
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800247{
248 int i = 0;
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700249 int encryptable = 0;
250 int error_count = 0;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800251 int mret;
William Roberts071f28a2014-01-14 14:33:44 -0500252 int mount_errno;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800253
Ken Sumrallab6b8522013-02-13 12:58:40 -0800254 if (!fstab) {
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700255 return -1;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800256 }
257
Ken Sumrallab6b8522013-02-13 12:58:40 -0800258 for (i = 0; i < fstab->num_entries; i++) {
259 /* Don't mount entries that are managed by vold */
Ken Sumrall6c2c1212013-02-22 17:36:21 -0800260 if (fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) {
Ken Sumrallab6b8522013-02-13 12:58:40 -0800261 continue;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800262 }
263
Ken Sumrall5bc31a22013-07-08 19:11:55 -0700264 /* Skip swap and raw partition entries such as boot, recovery, etc */
265 if (!strcmp(fstab->recs[i].fs_type, "swap") ||
266 !strcmp(fstab->recs[i].fs_type, "emmc") ||
Ken Sumrallab6b8522013-02-13 12:58:40 -0800267 !strcmp(fstab->recs[i].fs_type, "mtd")) {
268 continue;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800269 }
270
Ken Sumrallab6b8522013-02-13 12:58:40 -0800271 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
272 wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
273 }
274
275 if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
276 check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
277 fstab->recs[i].mount_point);
278 }
279
Geremy Condracd642fc2014-04-02 13:42:06 -0700280 if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
281 !device_is_debuggable()) {
Geremy Condra3ad3d1c2013-02-22 18:11:41 -0800282 if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
283 ERROR("Could not set up verified partition, skipping!");
284 continue;
285 }
286 }
287
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700288 mret = __mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point,
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700289 fstab->recs[i].fs_type, fstab->recs[i].flags,
290 fstab->recs[i].fs_options);
Geremy Condra3ad3d1c2013-02-22 18:11:41 -0800291
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800292 if (!mret) {
Paul Lawrence166fa3d2014-02-03 13:27:49 -0800293 /* If this is encryptable, need to trigger encryption */
294 if ((fstab->recs[i].fs_mgr_flags & MF_CRYPT)) {
295 if (serial_matches() && umount(fstab->recs[i].mount_point) == 0) {
296 if (!encryptable) {
297 encryptable = 2;
298 } else {
299 ERROR("Only one encryptable/encrypted partition supported");
300 encryptable = 1;
301 }
302 } else {
303 INFO("Could not umount %s - allow continue unencrypted",
304 fstab->recs[i].mount_point);
305 continue;
306 }
307 }
308
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800309 /* Success! Go get the next one */
310 continue;
311 }
312
William Roberts071f28a2014-01-14 14:33:44 -0500313 /* back up errno as partition_wipe clobbers the value */
314 mount_errno = errno;
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700315 /* mount(2) returned an error, check if it's encryptable and deal with it */
Mohamad Ayyash611f5e92014-03-12 15:00:06 -0700316 if (mount_errno != EBUSY && mount_errno != EACCES &&
317 (fstab->recs[i].fs_mgr_flags & MF_CRYPT) &&
Ken Sumrallab6b8522013-02-13 12:58:40 -0800318 !partition_wiped(fstab->recs[i].blk_device)) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800319 /* Need to mount a tmpfs at this mountpoint for now, and set
320 * properties that vold will query later for decrypting
321 */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800322 if (mount("tmpfs", fstab->recs[i].mount_point, "tmpfs",
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700323 MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS) < 0) {
324 ERROR("Cannot mount tmpfs filesystem for encryptable fs at %s error: %s\n",
325 fstab->recs[i].mount_point, strerror(errno));
326 ++error_count;
327 continue;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800328 }
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700329 encryptable = 1;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800330 } else {
William Roberts071f28a2014-01-14 14:33:44 -0500331 ERROR("Failed to mount an un-encryptable or wiped partition on"
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700332 "%s at %s options: %s error: %s\n",
333 fstab->recs[i].blk_device, fstab->recs[i].mount_point,
334 fstab->recs[i].fs_options, strerror(mount_errno));
335 ++error_count;
336 continue;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800337 }
338 }
339
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700340 if (error_count) {
341 return -1;
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700342 } else {
Paul Lawrence166fa3d2014-02-03 13:27:49 -0800343 return encryptable;
Mohamad Ayyash38afe5f2014-03-10 15:40:29 -0700344 }
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800345}
346
Ken Sumrallab6b8522013-02-13 12:58:40 -0800347/* If tmp_mount_point is non-null, mount the filesystem there. This is for the
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800348 * tmp mount we do to check the user password
349 */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800350int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
351 char *tmp_mount_point)
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800352{
353 int i = 0;
354 int ret = -1;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800355 char *m;
356
Ken Sumrallab6b8522013-02-13 12:58:40 -0800357 if (!fstab) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800358 return ret;
359 }
360
Ken Sumrallab6b8522013-02-13 12:58:40 -0800361 for (i = 0; i < fstab->num_entries; i++) {
362 if (!fs_match(fstab->recs[i].mount_point, n_name)) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800363 continue;
364 }
365
366 /* We found our match */
Ken Sumrall5bc31a22013-07-08 19:11:55 -0700367 /* If this swap or a raw partition, report an error */
368 if (!strcmp(fstab->recs[i].fs_type, "swap") ||
369 !strcmp(fstab->recs[i].fs_type, "emmc") ||
Ken Sumrallab6b8522013-02-13 12:58:40 -0800370 !strcmp(fstab->recs[i].fs_type, "mtd")) {
371 ERROR("Cannot mount filesystem of type %s on %s\n",
372 fstab->recs[i].fs_type, n_blk_device);
373 goto out;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800374 }
375
Ken Sumrallab6b8522013-02-13 12:58:40 -0800376 /* First check the filesystem if requested */
377 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
378 wait_for_file(n_blk_device, WAIT_TIMEOUT);
379 }
380
381 if (fstab->recs[i].fs_mgr_flags & MF_CHECK) {
382 check_fs(n_blk_device, fstab->recs[i].fs_type,
383 fstab->recs[i].mount_point);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800384 }
385
Geremy Condracd642fc2014-04-02 13:42:06 -0700386 if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
387 !device_is_debuggable()) {
Geremy Condra3ad3d1c2013-02-22 18:11:41 -0800388 if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
389 ERROR("Could not set up verified partition, skipping!");
390 continue;
391 }
392 }
393
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800394 /* Now mount it where requested */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800395 if (tmp_mount_point) {
396 m = tmp_mount_point;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800397 } else {
Ken Sumrallab6b8522013-02-13 12:58:40 -0800398 m = fstab->recs[i].mount_point;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800399 }
Nick Kraleviche18c0d52013-04-16 16:41:32 -0700400 if (__mount(n_blk_device, m, fstab->recs[i].fs_type,
401 fstab->recs[i].flags, fstab->recs[i].fs_options)) {
William Roberts071f28a2014-01-14 14:33:44 -0500402 ERROR("Cannot mount filesystem on %s at %s options: %s error: %s\n",
403 n_blk_device, m, fstab->recs[i].fs_options, strerror(errno));
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800404 goto out;
405 } else {
406 ret = 0;
407 goto out;
408 }
409 }
410
411 /* We didn't find a match, say so and return an error */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800412 ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800413
414out:
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800415 return ret;
416}
417
418/*
419 * mount a tmpfs filesystem at the given point.
420 * return 0 on success, non-zero on failure.
421 */
422int fs_mgr_do_tmpfs_mount(char *n_name)
423{
424 int ret;
425
426 ret = mount("tmpfs", n_name, "tmpfs",
427 MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS);
428 if (ret < 0) {
429 ERROR("Cannot mount tmpfs filesystem at %s\n", n_name);
430 return -1;
431 }
432
433 /* Success */
434 return 0;
435}
436
Ken Sumrallab6b8522013-02-13 12:58:40 -0800437int fs_mgr_unmount_all(struct fstab *fstab)
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800438{
439 int i = 0;
440 int ret = 0;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800441
Ken Sumrallab6b8522013-02-13 12:58:40 -0800442 if (!fstab) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800443 return -1;
444 }
445
Ken Sumrallab6b8522013-02-13 12:58:40 -0800446 while (fstab->recs[i].blk_device) {
447 if (umount(fstab->recs[i].mount_point)) {
448 ERROR("Cannot unmount filesystem at %s\n", fstab->recs[i].mount_point);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800449 ret = -1;
450 }
451 i++;
452 }
453
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800454 return ret;
455}
Ken Sumrall5bc31a22013-07-08 19:11:55 -0700456
457/* This must be called after mount_all, because the mkswap command needs to be
458 * available.
459 */
460int fs_mgr_swapon_all(struct fstab *fstab)
461{
462 int i = 0;
463 int flags = 0;
464 int err = 0;
465 int ret = 0;
466 int status;
467 char *mkswap_argv[2] = {
468 MKSWAP_BIN,
469 NULL
470 };
471
472 if (!fstab) {
473 return -1;
474 }
475
476 for (i = 0; i < fstab->num_entries; i++) {
477 /* Skip non-swap entries */
478 if (strcmp(fstab->recs[i].fs_type, "swap")) {
479 continue;
480 }
481
482 if (fstab->recs[i].zram_size > 0) {
483 /* A zram_size was specified, so we need to configure the
484 * device. There is no point in having multiple zram devices
485 * on a system (all the memory comes from the same pool) so
486 * we can assume the device number is 0.
487 */
488 FILE *zram_fp;
489
490 zram_fp = fopen(ZRAM_CONF_DEV, "r+");
491 if (zram_fp == NULL) {
492 ERROR("Unable to open zram conf device " ZRAM_CONF_DEV);
493 ret = -1;
494 continue;
495 }
496 fprintf(zram_fp, "%d\n", fstab->recs[i].zram_size);
497 fclose(zram_fp);
498 }
499
500 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) {
501 wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
502 }
503
504 /* Initialize the swap area */
505 mkswap_argv[1] = fstab->recs[i].blk_device;
506 err = android_fork_execvp_ext(ARRAY_SIZE(mkswap_argv), mkswap_argv,
Ken Sumrall4eaf9052013-09-18 17:49:21 -0700507 &status, true, LOG_KLOG, false, NULL);
Ken Sumrall5bc31a22013-07-08 19:11:55 -0700508 if (err) {
509 ERROR("mkswap failed for %s\n", fstab->recs[i].blk_device);
510 ret = -1;
511 continue;
512 }
513
514 /* If -1, then no priority was specified in fstab, so don't set
515 * SWAP_FLAG_PREFER or encode the priority */
516 if (fstab->recs[i].swap_prio >= 0) {
517 flags = (fstab->recs[i].swap_prio << SWAP_FLAG_PRIO_SHIFT) &
518 SWAP_FLAG_PRIO_MASK;
519 flags |= SWAP_FLAG_PREFER;
520 } else {
521 flags = 0;
522 }
523 err = swapon(fstab->recs[i].blk_device, flags);
524 if (err) {
525 ERROR("swapon failed for %s\n", fstab->recs[i].blk_device);
526 ret = -1;
527 }
528 }
529
530 return ret;
531}
532
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800533/*
534 * key_loc must be at least PROPERTY_VALUE_MAX bytes long
535 *
Ken Sumrallab6b8522013-02-13 12:58:40 -0800536 * real_blk_device must be at least PROPERTY_VALUE_MAX bytes long
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800537 */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800538int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_device, int size)
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800539{
540 int i = 0;
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800541
Ken Sumrallab6b8522013-02-13 12:58:40 -0800542 if (!fstab) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800543 return -1;
544 }
545 /* Initialize return values to null strings */
546 if (key_loc) {
547 *key_loc = '\0';
548 }
Ken Sumrallab6b8522013-02-13 12:58:40 -0800549 if (real_blk_device) {
550 *real_blk_device = '\0';
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800551 }
552
553 /* Look for the encryptable partition to find the data */
Ken Sumrallab6b8522013-02-13 12:58:40 -0800554 for (i = 0; i < fstab->num_entries; i++) {
555 /* Don't deal with vold managed enryptable partitions here */
556 if (fstab->recs[i].fs_mgr_flags & MF_VOLDMANAGED) {
557 continue;
558 }
559 if (!(fstab->recs[i].fs_mgr_flags & MF_CRYPT)) {
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800560 continue;
561 }
562
563 /* We found a match */
564 if (key_loc) {
Ken Sumrallab6b8522013-02-13 12:58:40 -0800565 strlcpy(key_loc, fstab->recs[i].key_loc, size);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800566 }
Ken Sumrallab6b8522013-02-13 12:58:40 -0800567 if (real_blk_device) {
568 strlcpy(real_blk_device, fstab->recs[i].blk_device, size);
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800569 }
570 break;
571 }
572
Ken Sumrallc1bf8962012-01-06 19:09:42 -0800573 return 0;
574}