blob: 184674d4a81692289c7f3745cd39487475986560 [file] [log] [blame]
Paul Lawrence5f356482014-10-09 14:22:49 +00001/*
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
Dan Albert59bcbe22015-01-26 17:49:17 -080017#include <fcntl.h>
18#include <inttypes.h>
19#include <stdarg.h>
20#include <stdbool.h>
21#include <stdio.h>
22#include <sys/stat.h>
Paul Lawrence5f356482014-10-09 14:22:49 +000023
24#define TRACE_TAG TRACE_ADB
25#include "adb.h"
Paul Lawrence5f356482014-10-09 14:22:49 +000026#include "cutils/properties.h"
Dan Albert0ca996b2015-01-26 17:13:54 -080027#include "ext4_sb.h"
Dan Albert59bcbe22015-01-26 17:49:17 -080028#include "fs_mgr.h"
29#include "sysdeps.h"
Paul Lawrence5f356482014-10-09 14:22:49 +000030
31#define FSTAB_PREFIX "/fstab."
32struct fstab *fstab;
33
Dan Albert59bcbe22015-01-26 17:49:17 -080034#ifdef ALLOW_ADBD_DISABLE_VERITY
35static const bool kAllowDisableVerity = true;
36#else
37static const bool kAllowDisableVerity = false;
38#endif
39
Paul Lawrence5f356482014-10-09 14:22:49 +000040__attribute__((__format__(printf, 2, 3))) __nonnull((2))
41static void write_console(int fd, const char* format, ...)
42{
43 char buffer[256];
44 va_list args;
45 va_start (args, format);
46 vsnprintf (buffer, sizeof(buffer), format, args);
47 va_end (args);
48
49 adb_write(fd, buffer, strnlen(buffer, sizeof(buffer)));
50}
51
52static int get_target_device_size(int fd, const char *blk_device,
53 uint64_t *device_size)
54{
55 int data_device;
56 struct ext4_super_block sb;
57 struct fs_info info;
58
59 info.len = 0; /* Only len is set to 0 to ask the device for real size. */
60
61 data_device = adb_open(blk_device, O_RDONLY | O_CLOEXEC);
62 if (data_device < 0) {
63 write_console(fd, "Error opening block device (%s)\n", strerror(errno));
64 return -1;
65 }
66
67 if (lseek64(data_device, 1024, SEEK_SET) < 0) {
68 write_console(fd, "Error seeking to superblock\n");
69 adb_close(data_device);
70 return -1;
71 }
72
73 if (adb_read(data_device, &sb, sizeof(sb)) != sizeof(sb)) {
74 write_console(fd, "Error reading superblock\n");
75 adb_close(data_device);
76 return -1;
77 }
78
79 ext4_parse_sb(&sb, &info);
80 *device_size = info.len;
81
82 adb_close(data_device);
83 return 0;
84}
85
Paul Lawrence8ba2b022014-12-03 15:31:57 -080086/* Turn verity on/off */
87static int set_verity_enabled_state(int fd, const char *block_device,
88 const char* mount_point, bool enable)
Paul Lawrence5f356482014-10-09 14:22:49 +000089{
90 uint32_t magic_number;
Paul Lawrence8ba2b022014-12-03 15:31:57 -080091 const uint32_t new_magic = enable ? VERITY_METADATA_MAGIC_NUMBER
92 : VERITY_METADATA_MAGIC_DISABLE;
Paul Lawrence5f356482014-10-09 14:22:49 +000093 uint64_t device_length;
Sami Tolvanen5638a1a2015-01-02 13:30:50 +000094 int device = -1;
Paul Lawrence5f356482014-10-09 14:22:49 +000095 int retval = -1;
96
Sami Tolvanen5638a1a2015-01-02 13:30:50 +000097 if (make_block_device_writable(block_device)) {
98 write_console(fd, "Could not make block device %s writable (%s).\n",
99 block_device, strerror(errno));
100 goto errout;
101 }
102
Paul Lawrence5f356482014-10-09 14:22:49 +0000103 device = adb_open(block_device, O_RDWR | O_CLOEXEC);
104 if (device == -1) {
105 write_console(fd, "Could not open block device %s (%s).\n",
106 block_device, strerror(errno));
107 write_console(fd, "Maybe run adb remount?\n");
108 goto errout;
109 }
110
111 // find the start of the verity metadata
112 if (get_target_device_size(fd, (char*)block_device, &device_length) < 0) {
113 write_console(fd, "Could not get target device size.\n");
114 goto errout;
115 }
116
117 if (lseek64(device, device_length, SEEK_SET) < 0) {
118 write_console(fd,
119 "Could not seek to start of verity metadata block.\n");
120 goto errout;
121 }
122
123 // check the magic number
124 if (adb_read(device, &magic_number, sizeof(magic_number))
125 != sizeof(magic_number)) {
126 write_console(fd, "Couldn't read magic number!\n");
127 goto errout;
128 }
129
Paul Lawrence8ba2b022014-12-03 15:31:57 -0800130 if (!enable && magic_number == VERITY_METADATA_MAGIC_DISABLE) {
Paul Lawrence5f356482014-10-09 14:22:49 +0000131 write_console(fd, "Verity already disabled on %s\n", mount_point);
132 goto errout;
133 }
134
Paul Lawrence8ba2b022014-12-03 15:31:57 -0800135 if (enable && magic_number == VERITY_METADATA_MAGIC_NUMBER) {
136 write_console(fd, "Verity already enabled on %s\n", mount_point);
137 goto errout;
138 }
139
140 if (magic_number != VERITY_METADATA_MAGIC_NUMBER
141 && magic_number != VERITY_METADATA_MAGIC_DISABLE) {
Paul Lawrence5f356482014-10-09 14:22:49 +0000142 write_console(fd,
143 "Couldn't find verity metadata at offset %"PRIu64"!\n",
144 device_length);
145 goto errout;
146 }
147
148 if (lseek64(device, device_length, SEEK_SET) < 0) {
149 write_console(fd,
150 "Could not seek to start of verity metadata block.\n");
151 goto errout;
152 }
153
Paul Lawrence8ba2b022014-12-03 15:31:57 -0800154 if (adb_write(device, &new_magic, sizeof(new_magic)) != sizeof(new_magic)) {
Dan Albert59bcbe22015-01-26 17:49:17 -0800155 write_console(
156 fd, "Could not set verity %s flag on device %s with error %s\n",
157 enable ? "enabled" : "disabled",
158 block_device, strerror(errno));
Paul Lawrence5f356482014-10-09 14:22:49 +0000159 goto errout;
160 }
161
Paul Lawrence8ba2b022014-12-03 15:31:57 -0800162 write_console(fd, "Verity %s on %s\n",
163 enable ? "enabled" : "disabled",
164 mount_point);
Paul Lawrence5f356482014-10-09 14:22:49 +0000165 retval = 0;
166errout:
167 if (device != -1)
168 adb_close(device);
169 return retval;
170}
171
Paul Lawrence8ba2b022014-12-03 15:31:57 -0800172void set_verity_enabled_state_service(int fd, void* cookie)
Paul Lawrence5f356482014-10-09 14:22:49 +0000173{
Paul Lawrence8ba2b022014-12-03 15:31:57 -0800174 bool enable = (cookie != NULL);
Dan Albert59bcbe22015-01-26 17:49:17 -0800175 if (kAllowDisableVerity) {
176 char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
177 char propbuf[PROPERTY_VALUE_MAX];
178 int i;
179 bool any_changed = false;
Paul Lawrence5f356482014-10-09 14:22:49 +0000180
Dan Albert59bcbe22015-01-26 17:49:17 -0800181 property_get("ro.secure", propbuf, "0");
182 if (strcmp(propbuf, "1")) {
183 write_console(fd, "verity not enabled - ENG build\n");
184 goto errout;
185 }
186
187 property_get("ro.debuggable", propbuf, "0");
188 if (strcmp(propbuf, "1")) {
189 write_console(
190 fd, "verity cannot be disabled/enabled - USER build\n");
191 goto errout;
192 }
193
194 property_get("ro.hardware", propbuf, "");
195 snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s",
196 propbuf);
197
198 fstab = fs_mgr_read_fstab(fstab_filename);
199 if (!fstab) {
200 write_console(fd, "Failed to open %s\nMaybe run adb root?\n",
201 fstab_filename);
202 goto errout;
203 }
204
205 /* Loop through entries looking for ones that vold manages */
206 for (i = 0; i < fstab->num_entries; i++) {
207 if(fs_mgr_is_verified(&fstab->recs[i])) {
208 if (!set_verity_enabled_state(fd, fstab->recs[i].blk_device,
209 fstab->recs[i].mount_point,
210 enable)) {
211 any_changed = true;
212 }
213 }
214 }
215
216 if (any_changed) {
217 write_console(
218 fd, "Now reboot your device for settings to take effect\n");
219 }
220 } else {
221 write_console(fd, "%s-verity only works for userdebug builds\n",
222 enable ? "enable" : "disable");
Paul Lawrence5f356482014-10-09 14:22:49 +0000223 }
224
Bernhard Rosenkränzerf6b32542014-12-12 22:22:37 +0100225errout:
Paul Lawrence5f356482014-10-09 14:22:49 +0000226 adb_close(fd);
227}