Loading fastbootd/Android.mk +3 −1 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ LOCAL_SRC_FILES := \ commands/virtual_partitions.c \ fastbootd.c \ protocol.c \ secure.c \ transport.c \ trigger.c \ usb_linux_client.c \ Loading @@ -37,11 +38,12 @@ LOCAL_SRC_FILES := \ LOCAL_MODULE := fastbootd LOCAL_MODULE_TAGS := optional LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter -DFLASH_CERT LOCAL_LDFLAGS := -ldl LOCAL_SHARED_LIBRARIES := \ libhardware \ libcrypto \ libhardware_legacy LOCAL_STATIC_LIBRARIES := \ Loading fastbootd/commands.c +32 −7 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg) { int sz, atags_sz, new_atags_sz; int rv; unsigned kernel_actual; unsigned ramdisk_actual; unsigned second_actual; Loading @@ -59,9 +61,11 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg) void *ramdisk_ptr; void *second_ptr; struct boot_img_hdr *hdr; int sz, atags_sz, new_atags_sz; int rv; char *ptr = NULL, *atags_ptr = NULL, *new_atags = NULL; char *ptr = NULL; char *atags_ptr = NULL; char *new_atags = NULL; int data_fd = 0; D(DEBUG, "cmd_boot %s\n", arg); if (phandle->download_fd < 0) { Loading @@ -75,9 +79,18 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg) goto error; } sz = get_file_size(phandle->download_fd); // TODO: With cms we can also verify partition name included as // cms signed attribute if (flash_validate_certificate(phandle->download_fd, &data_fd) != 1) { fastboot_fail(phandle, "Access forbiden you need the certificate"); return; } sz = get_file_size(data_fd); ptr = (char *) mmap(NULL, sz, PROT_READ, MAP_POPULATE | MAP_PRIVATE, phandle->download_fd, 0); MAP_POPULATE | MAP_PRIVATE, data_fd, 0); hdr = (struct boot_img_hdr *) ptr; if (ptr == MAP_FAILED) { Loading Loading @@ -130,6 +143,7 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg) free(atags_ptr); munmap(ptr, sz); free(new_atags); close(data_fd); D(INFO, "Kexec going to reboot"); reboot(LINUX_REBOOT_CMD_KEXEC); Loading Loading @@ -256,6 +270,7 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg) char data[BOOT_MAGIC_SIZE]; char path[PATH_MAX]; ssize_t header_sz = 0; int data_fd = 0; D(DEBUG, "cmd_flash %s\n", arg); Loading @@ -273,9 +288,14 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg) return; } if (flash_validate_certificate(phandle->download_fd, &data_fd) != 1) { fastboot_fail(phandle, "Access forbiden you need certificate"); return; } // TODO: Maybe its goot idea to check whether the partition is just bootable partition if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) { if (read_data_once(phandle->download_fd, data, BOOT_MAGIC_SIZE) < BOOT_MAGIC_SIZE) { if (read_data_once(data_fd, data, BOOT_MAGIC_SIZE) < BOOT_MAGIC_SIZE) { fastboot_fail(phandle, "incoming data read error, cannot read boot header"); return; } Loading @@ -287,7 +307,10 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg) partition = flash_get_partiton(path); sz = get_file_size64(phandle->download_fd); sz = get_file_size64(data_fd); sz -= header_sz; if (sz > get_file_size64(partition)) { flash_close(partition); D(WARN, "size of file too large"); Loading @@ -304,6 +327,8 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg) D(INFO, "partition '%s' updated\n", arg); flash_close(partition); close(data_fd); //TODO: check who is closing phandle->download_fd fastboot_okay(phandle, ""); } Loading fastbootd/commands/flash.c +47 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,9 @@ #include "utils.h" #include "commands/partitions.h" #ifdef FLASH_CERT #include "secure.h" #endif #define ALLOWED_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-." #define BUFFER_SIZE 1024 * 1024 Loading Loading @@ -112,3 +115,47 @@ int flash_write(int partition_fd, int data_fd, ssize_t size, ssize_t skip) return 0; } #ifdef FLASH_CERT int flash_validate_certificate(int signed_fd, int *data_fd) { int ret = 0; const char *cert_path; X509_STORE *store = NULL; CMS_ContentInfo *content_info; BIO *content; cert_path = fastboot_getvar("certificate-path"); if (!strcmp(cert_path, "")) { D(ERR, "could not find cert-key value in config file"); goto finish; } store = cert_store_from_path(cert_path); if (store == NULL) { D(ERR, "unable to create certification store"); goto finish; } if (cert_read(signed_fd, &content_info, &content)) { D(ERR, "reading data failed"); goto finish; } ret = cert_verify(content, content_info, store, data_fd); cert_release(content, content_info); return ret; finish: if (store != NULL) cert_release_store(store); return ret; } #else int flash_validate_certificate(int signed_fd, int *data_fd) { return 1; } #endif fastbootd/commands/flash.h +2 −0 Original line number Diff line number Diff line Loading @@ -58,5 +58,7 @@ static inline ssize_t read_data_once(int fd, char *buffer, ssize_t size) { return readcount; } int flash_validate_certificate(int signed_fd, int *data_fd); #endif fastbootd/fastbootd.c +2 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include "debug.h" #include "trigger.h" #include "secure.h" unsigned int debug_level = DEBUG; Loading @@ -36,6 +37,7 @@ int main(int argc, char **argv) klog_init(); klog_set_level(6); cert_init_crypto(); config_init(); load_trigger(); commands_init(); Loading Loading
fastbootd/Android.mk +3 −1 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ LOCAL_SRC_FILES := \ commands/virtual_partitions.c \ fastbootd.c \ protocol.c \ secure.c \ transport.c \ trigger.c \ usb_linux_client.c \ Loading @@ -37,11 +38,12 @@ LOCAL_SRC_FILES := \ LOCAL_MODULE := fastbootd LOCAL_MODULE_TAGS := optional LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter -DFLASH_CERT LOCAL_LDFLAGS := -ldl LOCAL_SHARED_LIBRARIES := \ libhardware \ libcrypto \ libhardware_legacy LOCAL_STATIC_LIBRARIES := \ Loading
fastbootd/commands.c +32 −7 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg) { int sz, atags_sz, new_atags_sz; int rv; unsigned kernel_actual; unsigned ramdisk_actual; unsigned second_actual; Loading @@ -59,9 +61,11 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg) void *ramdisk_ptr; void *second_ptr; struct boot_img_hdr *hdr; int sz, atags_sz, new_atags_sz; int rv; char *ptr = NULL, *atags_ptr = NULL, *new_atags = NULL; char *ptr = NULL; char *atags_ptr = NULL; char *new_atags = NULL; int data_fd = 0; D(DEBUG, "cmd_boot %s\n", arg); if (phandle->download_fd < 0) { Loading @@ -75,9 +79,18 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg) goto error; } sz = get_file_size(phandle->download_fd); // TODO: With cms we can also verify partition name included as // cms signed attribute if (flash_validate_certificate(phandle->download_fd, &data_fd) != 1) { fastboot_fail(phandle, "Access forbiden you need the certificate"); return; } sz = get_file_size(data_fd); ptr = (char *) mmap(NULL, sz, PROT_READ, MAP_POPULATE | MAP_PRIVATE, phandle->download_fd, 0); MAP_POPULATE | MAP_PRIVATE, data_fd, 0); hdr = (struct boot_img_hdr *) ptr; if (ptr == MAP_FAILED) { Loading Loading @@ -130,6 +143,7 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg) free(atags_ptr); munmap(ptr, sz); free(new_atags); close(data_fd); D(INFO, "Kexec going to reboot"); reboot(LINUX_REBOOT_CMD_KEXEC); Loading Loading @@ -256,6 +270,7 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg) char data[BOOT_MAGIC_SIZE]; char path[PATH_MAX]; ssize_t header_sz = 0; int data_fd = 0; D(DEBUG, "cmd_flash %s\n", arg); Loading @@ -273,9 +288,14 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg) return; } if (flash_validate_certificate(phandle->download_fd, &data_fd) != 1) { fastboot_fail(phandle, "Access forbiden you need certificate"); return; } // TODO: Maybe its goot idea to check whether the partition is just bootable partition if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) { if (read_data_once(phandle->download_fd, data, BOOT_MAGIC_SIZE) < BOOT_MAGIC_SIZE) { if (read_data_once(data_fd, data, BOOT_MAGIC_SIZE) < BOOT_MAGIC_SIZE) { fastboot_fail(phandle, "incoming data read error, cannot read boot header"); return; } Loading @@ -287,7 +307,10 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg) partition = flash_get_partiton(path); sz = get_file_size64(phandle->download_fd); sz = get_file_size64(data_fd); sz -= header_sz; if (sz > get_file_size64(partition)) { flash_close(partition); D(WARN, "size of file too large"); Loading @@ -304,6 +327,8 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg) D(INFO, "partition '%s' updated\n", arg); flash_close(partition); close(data_fd); //TODO: check who is closing phandle->download_fd fastboot_okay(phandle, ""); } Loading
fastbootd/commands/flash.c +47 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,9 @@ #include "utils.h" #include "commands/partitions.h" #ifdef FLASH_CERT #include "secure.h" #endif #define ALLOWED_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-." #define BUFFER_SIZE 1024 * 1024 Loading Loading @@ -112,3 +115,47 @@ int flash_write(int partition_fd, int data_fd, ssize_t size, ssize_t skip) return 0; } #ifdef FLASH_CERT int flash_validate_certificate(int signed_fd, int *data_fd) { int ret = 0; const char *cert_path; X509_STORE *store = NULL; CMS_ContentInfo *content_info; BIO *content; cert_path = fastboot_getvar("certificate-path"); if (!strcmp(cert_path, "")) { D(ERR, "could not find cert-key value in config file"); goto finish; } store = cert_store_from_path(cert_path); if (store == NULL) { D(ERR, "unable to create certification store"); goto finish; } if (cert_read(signed_fd, &content_info, &content)) { D(ERR, "reading data failed"); goto finish; } ret = cert_verify(content, content_info, store, data_fd); cert_release(content, content_info); return ret; finish: if (store != NULL) cert_release_store(store); return ret; } #else int flash_validate_certificate(int signed_fd, int *data_fd) { return 1; } #endif
fastbootd/commands/flash.h +2 −0 Original line number Diff line number Diff line Loading @@ -58,5 +58,7 @@ static inline ssize_t read_data_once(int fd, char *buffer, ssize_t size) { return readcount; } int flash_validate_certificate(int signed_fd, int *data_fd); #endif
fastbootd/fastbootd.c +2 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include "debug.h" #include "trigger.h" #include "secure.h" unsigned int debug_level = DEBUG; Loading @@ -36,6 +37,7 @@ int main(int argc, char **argv) klog_init(); klog_set_level(6); cert_init_crypto(); config_init(); load_trigger(); commands_init(); Loading