Home | History | Annotate | Download | only in adb
      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