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