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 #define TRACE_TAG TRACE_ADB 18 19 #include "sysdeps.h" 20 21 #include <fcntl.h> 22 #include <inttypes.h> 23 #include <stdarg.h> 24 #include <stdio.h> 25 #include <sys/stat.h> 26 27 #include "cutils/properties.h" 28 29 #include "adb.h" 30 #include "adb_io.h" 31 #include "ext4_sb.h" 32 #include "fs_mgr.h" 33 #include "remount_service.h" 34 35 #define FSTAB_PREFIX "/fstab." 36 struct fstab *fstab; 37 38 #ifdef ALLOW_ADBD_DISABLE_VERITY 39 static const bool kAllowDisableVerity = true; 40 #else 41 static const bool kAllowDisableVerity = false; 42 #endif 43 44 static int get_target_device_size(int fd, const char *blk_device, 45 uint64_t *device_size) 46 { 47 int data_device; 48 struct ext4_super_block sb; 49 struct fs_info info; 50 51 info.len = 0; /* Only len is set to 0 to ask the device for real size. */ 52 53 data_device = adb_open(blk_device, O_RDONLY | O_CLOEXEC); 54 if (data_device < 0) { 55 WriteFdFmt(fd, "Error opening block device (%s)\n", strerror(errno)); 56 return -1; 57 } 58 59 if (lseek64(data_device, 1024, SEEK_SET) < 0) { 60 WriteFdFmt(fd, "Error seeking to superblock\n"); 61 adb_close(data_device); 62 return -1; 63 } 64 65 if (adb_read(data_device, &sb, sizeof(sb)) != sizeof(sb)) { 66 WriteFdFmt(fd, "Error reading superblock\n"); 67 adb_close(data_device); 68 return -1; 69 } 70 71 ext4_parse_sb(&sb, &info); 72 *device_size = info.len; 73 74 adb_close(data_device); 75 return 0; 76 } 77 78 /* Turn verity on/off */ 79 static int set_verity_enabled_state(int fd, const char *block_device, 80 const char* mount_point, bool enable) 81 { 82 uint32_t magic_number; 83 const uint32_t new_magic = enable ? VERITY_METADATA_MAGIC_NUMBER 84 : VERITY_METADATA_MAGIC_DISABLE; 85 uint64_t device_length = 0; 86 int device = -1; 87 int retval = -1; 88 89 if (!make_block_device_writable(block_device)) { 90 WriteFdFmt(fd, "Could not make block device %s writable (%s).\n", 91 block_device, strerror(errno)); 92 goto errout; 93 } 94 95 device = adb_open(block_device, O_RDWR | O_CLOEXEC); 96 if (device == -1) { 97 WriteFdFmt(fd, "Could not open block device %s (%s).\n", block_device, strerror(errno)); 98 WriteFdFmt(fd, "Maybe run adb remount?\n"); 99 goto errout; 100 } 101 102 // find the start of the verity metadata 103 if (get_target_device_size(fd, (char*)block_device, &device_length) < 0) { 104 WriteFdFmt(fd, "Could not get target device size.\n"); 105 goto errout; 106 } 107 108 if (lseek64(device, device_length, SEEK_SET) < 0) { 109 WriteFdFmt(fd, "Could not seek to start of verity metadata block.\n"); 110 goto errout; 111 } 112 113 // check the magic number 114 if (adb_read(device, &magic_number, sizeof(magic_number)) != sizeof(magic_number)) { 115 WriteFdFmt(fd, "Couldn't read magic number!\n"); 116 goto errout; 117 } 118 119 if (!enable && magic_number == VERITY_METADATA_MAGIC_DISABLE) { 120 WriteFdFmt(fd, "Verity already disabled on %s\n", mount_point); 121 goto errout; 122 } 123 124 if (enable && magic_number == VERITY_METADATA_MAGIC_NUMBER) { 125 WriteFdFmt(fd, "Verity already enabled on %s\n", mount_point); 126 goto errout; 127 } 128 129 if (magic_number != VERITY_METADATA_MAGIC_NUMBER 130 && magic_number != VERITY_METADATA_MAGIC_DISABLE) { 131 WriteFdFmt(fd, "Couldn't find verity metadata at offset %" PRIu64 "!\n", device_length); 132 goto errout; 133 } 134 135 if (lseek64(device, device_length, SEEK_SET) < 0) { 136 WriteFdFmt(fd, "Could not seek to start of verity metadata block.\n"); 137 goto errout; 138 } 139 140 if (adb_write(device, &new_magic, sizeof(new_magic)) != sizeof(new_magic)) { 141 WriteFdFmt(fd, "Could not set verity %s flag on device %s with error %s\n", 142 enable ? "enabled" : "disabled", 143 block_device, strerror(errno)); 144 goto errout; 145 } 146 147 WriteFdFmt(fd, "Verity %s on %s\n", enable ? "enabled" : "disabled", mount_point); 148 retval = 0; 149 errout: 150 if (device != -1) 151 adb_close(device); 152 return retval; 153 } 154 155 void set_verity_enabled_state_service(int fd, void* cookie) 156 { 157 bool enable = (cookie != NULL); 158 if (kAllowDisableVerity) { 159 char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; 160 char propbuf[PROPERTY_VALUE_MAX]; 161 int i; 162 bool any_changed = false; 163 164 property_get("ro.secure", propbuf, "0"); 165 if (strcmp(propbuf, "1")) { 166 WriteFdFmt(fd, "verity not enabled - ENG build\n"); 167 goto errout; 168 } 169 170 property_get("ro.debuggable", propbuf, "0"); 171 if (strcmp(propbuf, "1")) { 172 WriteFdFmt(fd, "verity cannot be disabled/enabled - USER build\n"); 173 goto errout; 174 } 175 176 property_get("ro.hardware", propbuf, ""); 177 snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", 178 propbuf); 179 180 fstab = fs_mgr_read_fstab(fstab_filename); 181 if (!fstab) { 182 WriteFdFmt(fd, "Failed to open %s\nMaybe run adb root?\n", fstab_filename); 183 goto errout; 184 } 185 186 /* Loop through entries looking for ones that vold manages */ 187 for (i = 0; i < fstab->num_entries; i++) { 188 if(fs_mgr_is_verified(&fstab->recs[i])) { 189 if (!set_verity_enabled_state(fd, fstab->recs[i].blk_device, 190 fstab->recs[i].mount_point, 191 enable)) { 192 any_changed = true; 193 } 194 } 195 } 196 197 if (any_changed) { 198 WriteFdFmt(fd, "Now reboot your device for settings to take effect\n"); 199 } 200 } else { 201 WriteFdFmt(fd, "%s-verity only works for userdebug builds\n", 202 enable ? "enable" : "disable"); 203 } 204 205 errout: 206 adb_close(fd); 207 } 208