Home | History | Annotate | Download | only in boot_control
      1 /*
      2  * Copyright (C) 2015 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 <endian.h>
     18 #include <errno.h>
     19 #include <fcntl.h>
     20 #include <string.h>
     21 
     22 #include <string>
     23 
     24 #include <android-base/file.h>
     25 #include <android-base/logging.h>
     26 #include <android-base/properties.h>
     27 #include <android-base/stringprintf.h>
     28 #include <android-base/unique_fd.h>
     29 #include <hardware/boot_control.h>
     30 #include <hardware/hardware.h>
     31 
     32 #include <bootloader_message/bootloader_message.h>
     33 
     34 struct boot_control_private_t {
     35   // The base struct needs to be first in the list.
     36   boot_control_module_t base;
     37 
     38   // Whether this struct was initialized with data from the bootloader message
     39   // that doesn't change until next reboot.
     40   bool initialized;
     41 
     42   // The path to the misc_device as reported in the fstab.
     43   const char* misc_device;
     44 
     45   // The number of slots present on the device.
     46   unsigned int num_slots;
     47 
     48   // The slot where we are running from.
     49   unsigned int current_slot;
     50 };
     51 
     52 namespace {
     53 
     54 // The number of boot attempts that should be made from a new slot before
     55 // rolling back to the previous slot.
     56 constexpr unsigned int kDefaultBootAttempts = 7;
     57 static_assert(kDefaultBootAttempts < 8, "tries_remaining field only has 3 bits");
     58 
     59 constexpr unsigned int kMaxNumSlots =
     60     sizeof(bootloader_control::slot_info) / sizeof(bootloader_control::slot_info[0]);
     61 constexpr const char* kSlotSuffixes[kMaxNumSlots] = { "_a", "_b", "_c", "_d" };
     62 constexpr off_t kBootloaderControlOffset = offsetof(bootloader_message_ab, slot_suffix);
     63 
     64 static uint32_t CRC32(const uint8_t* buf, size_t size) {
     65   static uint32_t crc_table[256];
     66 
     67   // Compute the CRC-32 table only once.
     68   if (!crc_table[1]) {
     69     for (uint32_t i = 0; i < 256; ++i) {
     70       uint32_t crc = i;
     71       for (uint32_t j = 0; j < 8; ++j) {
     72         uint32_t mask = -(crc & 1);
     73         crc = (crc >> 1) ^ (0xEDB88320 & mask);
     74       }
     75       crc_table[i] = crc;
     76     }
     77   }
     78 
     79   uint32_t ret = -1;
     80   for (size_t i = 0; i < size; ++i) {
     81     ret = (ret >> 8) ^ crc_table[(ret ^ buf[i]) & 0xFF];
     82   }
     83 
     84   return ~ret;
     85 }
     86 
     87 // Return the little-endian representation of the CRC-32 of the first fields
     88 // in |boot_ctrl| up to the crc32_le field.
     89 uint32_t BootloaderControlLECRC(const bootloader_control* boot_ctrl) {
     90   return htole32(
     91       CRC32(reinterpret_cast<const uint8_t*>(boot_ctrl), offsetof(bootloader_control, crc32_le)));
     92 }
     93 
     94 bool LoadBootloaderControl(const char* misc_device, bootloader_control* buffer) {
     95   android::base::unique_fd fd(open(misc_device, O_RDONLY));
     96   if (fd.get() == -1) {
     97     PLOG(ERROR) << "failed to open " << misc_device;
     98     return false;
     99   }
    100   if (lseek(fd, kBootloaderControlOffset, SEEK_SET) != kBootloaderControlOffset) {
    101     PLOG(ERROR) << "failed to lseek " << misc_device;
    102     return false;
    103   }
    104   if (!android::base::ReadFully(fd.get(), buffer, sizeof(bootloader_control))) {
    105     PLOG(ERROR) << "failed to read " << misc_device;
    106     return false;
    107   }
    108   return true;
    109 }
    110 
    111 bool UpdateAndSaveBootloaderControl(const char* misc_device, bootloader_control* buffer) {
    112   buffer->crc32_le = BootloaderControlLECRC(buffer);
    113   android::base::unique_fd fd(open(misc_device, O_WRONLY | O_SYNC));
    114   if (fd.get() == -1) {
    115     PLOG(ERROR) << "failed to open " << misc_device;
    116     return false;
    117   }
    118   if (lseek(fd.get(), kBootloaderControlOffset, SEEK_SET) != kBootloaderControlOffset) {
    119     PLOG(ERROR) << "failed to lseek " << misc_device;
    120     return false;
    121   }
    122   if (!android::base::WriteFully(fd.get(), buffer, sizeof(bootloader_control))) {
    123     PLOG(ERROR) << "failed to write " << misc_device;
    124     return false;
    125   }
    126   return true;
    127 }
    128 
    129 void InitDefaultBootloaderControl(const boot_control_private_t* module,
    130                                   bootloader_control* boot_ctrl) {
    131   memset(boot_ctrl, 0, sizeof(*boot_ctrl));
    132 
    133   if (module->current_slot < kMaxNumSlots) {
    134     strlcpy(boot_ctrl->slot_suffix, kSlotSuffixes[module->current_slot],
    135             sizeof(boot_ctrl->slot_suffix));
    136   }
    137   boot_ctrl->magic = BOOT_CTRL_MAGIC;
    138   boot_ctrl->version = BOOT_CTRL_VERSION;
    139 
    140   // Figure out the number of slots by checking if the partitions exist,
    141   // otherwise assume the maximum supported by the header.
    142   boot_ctrl->nb_slot = kMaxNumSlots;
    143   std::string base_path = module->misc_device;
    144   size_t last_path_sep = base_path.rfind('/');
    145   if (last_path_sep != std::string::npos) {
    146     // We test the existence of the "boot" partition on each possible slot,
    147     // which is a partition required by Android Bootloader Requirements.
    148     base_path = base_path.substr(0, last_path_sep + 1) + "boot";
    149     int last_existing_slot = -1;
    150     int first_missing_slot = -1;
    151     for (unsigned int slot = 0; slot < kMaxNumSlots; ++slot) {
    152       std::string partition_path = base_path + kSlotSuffixes[slot];
    153       struct stat part_stat;
    154       int err = stat(partition_path.c_str(), &part_stat);
    155       if (!err) {
    156         last_existing_slot = slot;
    157         LOG(INFO) << "Found slot: " << kSlotSuffixes[slot];
    158       } else if (err < 0 && errno == ENOENT && first_missing_slot == -1) {
    159         first_missing_slot = slot;
    160       }
    161     }
    162     // We only declare that we found the actual number of slots if we found all
    163     // the boot partitions up to the number of slots, and no boot partition
    164     // after that. Not finding any of the boot partitions implies a problem so
    165     // we just leave the number of slots in the maximum value.
    166     if ((last_existing_slot != -1 && last_existing_slot + 1 == first_missing_slot) ||
    167         (first_missing_slot == -1 && last_existing_slot + 1 == kMaxNumSlots)) {
    168       boot_ctrl->nb_slot = last_existing_slot + 1;
    169       LOG(INFO) << "Found a system with " << last_existing_slot + 1 << " slots.";
    170     }
    171   }
    172 
    173   for (unsigned int slot = 0; slot < kMaxNumSlots; ++slot) {
    174     slot_metadata entry = {};
    175 
    176     if (slot < boot_ctrl->nb_slot) {
    177       entry.priority = 7;
    178       entry.tries_remaining = kDefaultBootAttempts;
    179       entry.successful_boot = 0;
    180     } else {
    181       entry.priority = 0;  // Unbootable
    182     }
    183 
    184     // When the boot_control stored on disk is invalid, we assume that the
    185     // current slot is successful. The bootloader should repair this situation
    186     // before booting and write a valid boot_control slot, so if we reach this
    187     // stage it means that the misc partition was corrupted since boot.
    188     if (module->current_slot == slot) {
    189       entry.successful_boot = 1;
    190     }
    191 
    192     boot_ctrl->slot_info[slot] = entry;
    193   }
    194   boot_ctrl->recovery_tries_remaining = 0;
    195 
    196   boot_ctrl->crc32_le = BootloaderControlLECRC(boot_ctrl);
    197 }
    198 
    199 // Return the index of the slot suffix passed or -1 if not a valid slot suffix.
    200 int SlotSuffixToIndex(const char* suffix) {
    201   for (unsigned int slot = 0; slot < kMaxNumSlots; ++slot) {
    202     if (!strcmp(kSlotSuffixes[slot], suffix)) return slot;
    203   }
    204   return -1;
    205 }
    206 
    207 // Initialize the boot_control_private struct with the information from
    208 // the bootloader_message buffer stored in |boot_ctrl|. Returns whether the
    209 // initialization succeeded.
    210 bool BootControl_lazyInitialization(boot_control_private_t* module) {
    211   if (module->initialized) return true;
    212 
    213   // Initialize the current_slot from the read-only property. If the property
    214   // was not set (from either the command line or the device tree), we can later
    215   // initialize it from the bootloader_control struct.
    216   std::string suffix_prop = android::base::GetProperty("ro.boot.slot_suffix", "");
    217   module->current_slot = SlotSuffixToIndex(suffix_prop.c_str());
    218 
    219   std::string err;
    220   std::string device = get_bootloader_message_blk_device(&err);
    221   if (device.empty()) return false;
    222 
    223   bootloader_control boot_ctrl;
    224   if (!LoadBootloaderControl(device.c_str(), &boot_ctrl)) return false;
    225 
    226   // Note that since there isn't a module unload function this memory is leaked.
    227   module->misc_device = strdup(device.c_str());
    228   module->initialized = true;
    229 
    230   // Validate the loaded data, otherwise we will destroy it and re-initialize it
    231   // with the current information.
    232   uint32_t computed_crc32 = BootloaderControlLECRC(&boot_ctrl);
    233   if (boot_ctrl.crc32_le != computed_crc32) {
    234     LOG(WARNING) << "Invalid boot control found, expected CRC-32 0x" << std::hex << computed_crc32
    235                  << " but found 0x" << std::hex << boot_ctrl.crc32_le << ". Re-initializing.";
    236     InitDefaultBootloaderControl(module, &boot_ctrl);
    237     UpdateAndSaveBootloaderControl(device.c_str(), &boot_ctrl);
    238   }
    239 
    240   module->num_slots = boot_ctrl.nb_slot;
    241   return true;
    242 }
    243 
    244 void BootControl_init(boot_control_module_t* module) {
    245   BootControl_lazyInitialization(reinterpret_cast<boot_control_private_t*>(module));
    246 }
    247 
    248 unsigned int BootControl_getNumberSlots(boot_control_module_t* module) {
    249   return reinterpret_cast<boot_control_private_t*>(module)->num_slots;
    250 }
    251 
    252 unsigned int BootControl_getCurrentSlot(boot_control_module_t* module) {
    253   return reinterpret_cast<boot_control_private_t*>(module)->current_slot;
    254 }
    255 
    256 int BootControl_markBootSuccessful(boot_control_module_t* module) {
    257   boot_control_private_t* const bootctrl_module = reinterpret_cast<boot_control_private_t*>(module);
    258 
    259   bootloader_control bootctrl;
    260   if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1;
    261 
    262   bootctrl.slot_info[bootctrl_module->current_slot].successful_boot = 1;
    263   // tries_remaining == 0 means that the slot is not bootable anymore, make
    264   // sure we mark the current slot as bootable if it succeeds in the last
    265   // attempt.
    266   bootctrl.slot_info[bootctrl_module->current_slot].tries_remaining = 1;
    267   if (!UpdateAndSaveBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1;
    268   return 0;
    269 }
    270 
    271 int BootControl_setActiveBootSlot(boot_control_module_t* module, unsigned int slot) {
    272   boot_control_private_t* const bootctrl_module = reinterpret_cast<boot_control_private_t*>(module);
    273 
    274   if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) {
    275     // Invalid slot number.
    276     return -1;
    277   }
    278 
    279   bootloader_control bootctrl;
    280   if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1;
    281 
    282   // Set every other slot with a lower priority than the new "active" slot.
    283   const unsigned int kActivePriority = 15;
    284   const unsigned int kActiveTries = 6;
    285   for (unsigned int i = 0; i < bootctrl_module->num_slots; ++i) {
    286     if (i != slot) {
    287       if (bootctrl.slot_info[i].priority >= kActivePriority)
    288         bootctrl.slot_info[i].priority = kActivePriority - 1;
    289     }
    290   }
    291 
    292   // Note that setting a slot as active doesn't change the successful bit.
    293   // The successful bit will only be changed by setSlotAsUnbootable().
    294   bootctrl.slot_info[slot].priority = kActivePriority;
    295   bootctrl.slot_info[slot].tries_remaining = kActiveTries;
    296 
    297   // Setting the current slot as active is a way to revert the operation that
    298   // set *another* slot as active at the end of an updater. This is commonly
    299   // used to cancel the pending update. We should only reset the verity_corrpted
    300   // bit when attempting a new slot, otherwise the verity bit on the current
    301   // slot would be flip.
    302   if (slot != bootctrl_module->current_slot) bootctrl.slot_info[slot].verity_corrupted = 0;
    303 
    304   if (!UpdateAndSaveBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1;
    305   return 0;
    306 }
    307 
    308 int BootControl_setSlotAsUnbootable(struct boot_control_module* module, unsigned int slot) {
    309   boot_control_private_t* const bootctrl_module = reinterpret_cast<boot_control_private_t*>(module);
    310 
    311   if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) {
    312     // Invalid slot number.
    313     return -1;
    314   }
    315 
    316   bootloader_control bootctrl;
    317   if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1;
    318 
    319   // The only way to mark a slot as unbootable, regardless of the priority is to
    320   // set the tries_remaining to 0.
    321   bootctrl.slot_info[slot].successful_boot = 0;
    322   bootctrl.slot_info[slot].tries_remaining = 0;
    323   if (!UpdateAndSaveBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1;
    324   return 0;
    325 }
    326 
    327 int BootControl_isSlotBootable(struct boot_control_module* module, unsigned int slot) {
    328   boot_control_private_t* const bootctrl_module = reinterpret_cast<boot_control_private_t*>(module);
    329 
    330   if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) {
    331     // Invalid slot number.
    332     return -1;
    333   }
    334 
    335   bootloader_control bootctrl;
    336   if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1;
    337 
    338   return bootctrl.slot_info[slot].tries_remaining;
    339 }
    340 
    341 int BootControl_isSlotMarkedSuccessful(struct boot_control_module* module, unsigned int slot) {
    342   boot_control_private_t* const bootctrl_module = reinterpret_cast<boot_control_private_t*>(module);
    343 
    344   if (slot >= kMaxNumSlots || slot >= bootctrl_module->num_slots) {
    345     // Invalid slot number.
    346     return -1;
    347   }
    348 
    349   bootloader_control bootctrl;
    350   if (!LoadBootloaderControl(bootctrl_module->misc_device, &bootctrl)) return -1;
    351 
    352   return bootctrl.slot_info[slot].successful_boot && bootctrl.slot_info[slot].tries_remaining;
    353 }
    354 
    355 const char* BootControl_getSuffix(boot_control_module_t* module, unsigned int slot) {
    356   if (slot >= kMaxNumSlots || slot >= reinterpret_cast<boot_control_private_t*>(module)->num_slots) {
    357     return NULL;
    358   }
    359   return kSlotSuffixes[slot];
    360 }
    361 
    362 static int BootControl_open(const hw_module_t* module __unused, const char* id __unused,
    363                             hw_device_t** device __unused) {
    364   /* Nothing to do currently. */
    365   return 0;
    366 }
    367 
    368 struct hw_module_methods_t BootControl_methods = {
    369   .open = BootControl_open,
    370 };
    371 
    372 }  // namespace
    373 
    374 boot_control_private_t HAL_MODULE_INFO_SYM = {
    375   .base =
    376       {
    377           .common =
    378               {
    379                   .tag = HARDWARE_MODULE_TAG,
    380                   .module_api_version = BOOT_CONTROL_MODULE_API_VERSION_0_1,
    381                   .hal_api_version = HARDWARE_HAL_API_VERSION,
    382                   .id = BOOT_CONTROL_HARDWARE_MODULE_ID,
    383                   .name = "AOSP reference bootctrl HAL",
    384                   .author = "The Android Open Source Project",
    385                   .methods = &BootControl_methods,
    386               },
    387           .init = BootControl_init,
    388           .getNumberSlots = BootControl_getNumberSlots,
    389           .getCurrentSlot = BootControl_getCurrentSlot,
    390           .markBootSuccessful = BootControl_markBootSuccessful,
    391           .setActiveBootSlot = BootControl_setActiveBootSlot,
    392           .setSlotAsUnbootable = BootControl_setSlotAsUnbootable,
    393           .isSlotBootable = BootControl_isSlotBootable,
    394           .getSuffix = BootControl_getSuffix,
    395           .isSlotMarkedSuccessful = BootControl_isSlotMarkedSuccessful,
    396       },
    397   .initialized = false,
    398   .misc_device = nullptr,
    399   .num_slots = 0,
    400   .current_slot = 0,
    401 };
    402