diff --git a/commands/loadenv.c b/commands/loadenv.c index 6469aff..bf01072 100644 --- a/commands/loadenv.c +++ b/commands/loadenv.c @@ -61,6 +61,10 @@ if (argc - optind < 1) { filename = default_environment_path_get(); + if (!filename) { + printf("Default environment path not set\n"); + return 1; + } } else { /* * /dev/defaultenv use to contain the defaultenvironment. diff --git a/commands/memtest.c b/commands/memtest.c index 99d4864..dc8f7db 100644 --- a/commands/memtest.c +++ b/commands/memtest.c @@ -33,12 +33,10 @@ { int ret; - printf("Testing memory space: " - "0x%08x -> 0x%08x:\n", - r->r->start, r->r->end); + printf("Testing memory space: %pa -> %pa:\n", + &r->r->start, &r->r->end); - remap_range((void *)r->r->start, r->r->end - - r->r->start + 1, cache_flag); + remap_range((void *)r->r->start, resource_size(r->r), cache_flag); ret = mem_test_bus_integrity(r->r->start, r->r->end); if (ret < 0) diff --git a/common/environment.c b/common/environment.c index 0edf34b..56a030e 100644 --- a/common/environment.c +++ b/common/environment.c @@ -256,9 +256,12 @@ struct action_data data = {}; void *buf = NULL, *wbuf; struct envfs_entry *env; + const char *defenv_path = default_environment_path_get(); if (!filename) - filename = default_environment_path_get(); + filename = defenv_path; + if (!filename) + return -ENOENT; if (!dirname) dirname = "/env"; @@ -365,7 +368,7 @@ ret = 0; #ifdef CONFIG_NVVAR - if (!strcmp(filename, default_environment_path_get())) + if (defenv_path && !strcmp(filename, defenv_path)) nv_var_set_clean(); #endif out: @@ -558,6 +561,8 @@ if (!filename) filename = default_environment_path_get(); + if (!filename) + return -ENOENT; if (!dir) dir = "/env"; diff --git a/common/memtest.c b/common/memtest.c index 0fc2046..44ddedd 100644 --- a/common/memtest.c +++ b/common/memtest.c @@ -131,8 +131,8 @@ /* * Ensure to leave with a cached on non used sdram regions. */ - remap_range((void *)r->r->start, r->r->end - - r->r->start + 1, MAP_DEFAULT); + remap_range((void *)r->r->start, resource_size(r->r), + MAP_DEFAULT); release_sdram_region(r->r); free(r); @@ -160,24 +160,29 @@ resource_size_t actual_value, volatile resource_size_t *address) { + /* + * expected_value and actual_value below are not really + * pointers, but we want them to be printed exactly the same + * as pointers would, so we use %pa regardless + */ printf("FAILURE (%s): " - "expected 0x%08x, actual 0x%08x at address 0x%08x.\n", - failure_description, expected_value, actual_value, - (resource_size_t)address); + "expected %pa, actual %pa at address %pa.\n", + failure_description, &expected_value, &actual_value, + &address); } int mem_test_bus_integrity(resource_size_t _start, resource_size_t _end) { - static const resource_size_t bitpattern[] = { - 0x00000001, /* single bit */ - 0x00000003, /* two adjacent bits */ - 0x00000007, /* three adjacent bits */ - 0x0000000F, /* four adjacent bits */ - 0x00000005, /* two non-adjacent bits */ - 0x00000015, /* three non-adjacent bits */ - 0x00000055, /* four non-adjacent bits */ - 0xAAAAAAAA, /* alternating 1/0 */ + static const uint64_t bitpattern[] = { + 0x0000000000000001ULL, /* single bit */ + 0x0000000000000003ULL, /* two adjacent bits */ + 0x0000000000000007ULL, /* three adjacent bits */ + 0x000000000000000FULL, /* four adjacent bits */ + 0x0000000000000005ULL, /* two non-adjacent bits */ + 0x0000000000000015ULL, /* three non-adjacent bits */ + 0x0000000000000055ULL, /* four non-adjacent bits */ + 0xAAAAAAAAAAAAAAAAULL, /* alternating 1/0 */ }; volatile resource_size_t *start, *dummy, num_words, val, readback, offset, @@ -217,7 +222,7 @@ * pattern and ~pattern). */ for (i = 0; i < ARRAY_SIZE(bitpattern); i++) { - val = bitpattern[i]; + val = (resource_size_t)bitpattern[i]; for (; val != 0; val <<= 1) { *start = val; @@ -282,8 +287,8 @@ * 01ffffff is perfect. */ - pattern = 0xAAAAAAAA; - anti_pattern = 0x55555555; + pattern = (resource_size_t)0xAAAAAAAAAAAAAAAAULL; + anti_pattern = (resource_size_t)0x5555555555555555ULL; /* * Write the default pattern at each of the diff --git a/common/startup.c b/common/startup.c index 8553849..832d326 100644 --- a/common/startup.c +++ b/common/startup.c @@ -73,16 +73,66 @@ #endif #ifdef CONFIG_ENV_HANDLING +static int check_overlap(const char *path) +{ + struct cdev *cenv, *cdisk, *cpart; + const char *name; + + name = devpath_to_name(path); + + if (name == path) + /* + * no /dev/ in front, so *path is some file. No need to + * check further. + */ + return 0; + + cenv = cdev_by_name(name); + if (!cenv) + return -EINVAL; + + cdisk = cenv->master; + + if (!cdisk) + return 0; + + list_for_each_entry(cpart, &cdisk->partitions, partition_entry) { + if (cpart == cenv) + continue; + + if (lregion_overlap(cpart->offset, cpart->size, + cenv->offset, cenv->size)) + goto conflict; + } + + return 0; + +conflict: + pr_err("Environment partition (0x%08llx-0x%08llx) " + "overlaps with partition %s (0x%08llx-0x%08llx), not using it\n", + cenv->offset, cenv->offset + cenv->offset + cenv->size - 1, + cpart->name, + cpart->offset, cpart->offset + cpart->offset + cpart->size - 1); + + return -EINVAL; +} + static int load_environment(void) { const char *default_environment_path; + int ret; default_environment_path = default_environment_path_get(); if (IS_ENABLED(CONFIG_DEFAULT_ENVIRONMENT)) defaultenv_load("/env", 0); - envfs_load(default_environment_path, "/env", 0); + ret = check_overlap(default_environment_path); + if (ret) + default_environment_path_set(NULL); + else + envfs_load(default_environment_path, "/env", 0); + nvvar_load(); return 0; diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 58d9230..23f2ab6 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -247,6 +247,11 @@ ret = stat(fentry->filename, &s); if (ret) { + device_detect_by_name(devpath_to_name(fentry->filename)); + ret = stat(fentry->filename, &s); + } + + if (ret) { if (fentry->flags & FILE_LIST_FLAG_CREATE) { ret = 0; type = "file"; @@ -609,6 +614,16 @@ fastboot_tx_print(f_fb, "OKAY"); } +static int rx_bytes_expected(struct f_fastboot *f_fb) +{ + int remaining = f_fb->download_size - f_fb->download_bytes; + + if (remaining >= EP_BUFFER_SIZE) + return EP_BUFFER_SIZE; + + return ALIGN(remaining, f_fb->out_ep->maxpacket); +} + static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req) { struct f_fastboot *f_fb = req->context; @@ -632,9 +647,7 @@ f_fb->download_bytes += req->actual; - req->length = f_fb->download_size - f_fb->download_bytes; - if (req->length > EP_BUFFER_SIZE) - req->length = EP_BUFFER_SIZE; + req->length = rx_bytes_expected(f_fb); show_progress(f_fb->download_bytes); @@ -687,9 +700,7 @@ struct usb_ep *ep = f_fb->out_ep; fastboot_tx_print(f_fb, "DATA%08x", f_fb->download_size); req->complete = rx_handler_dl_image; - req->length = EP_BUFFER_SIZE; - if (req->length < ep->maxpacket) - req->length = ep->maxpacket; + req->length = rx_bytes_expected(f_fb); } } diff --git a/include/common.h b/include/common.h index abbe73f..f52c7e4 100644 --- a/include/common.h +++ b/include/common.h @@ -157,4 +157,14 @@ return 1; } +static inline bool lregion_overlap(loff_t starta, loff_t lena, + loff_t startb, loff_t lenb) +{ + if (starta + lena <= startb) + return 0; + if (startb + lenb <= starta) + return 0; + return 1; +} + #endif /* __COMMON_H_ */ diff --git a/include/digest.h b/include/digest.h index 4552e58..a1cdbb2 100644 --- a/include/digest.h +++ b/include/digest.h @@ -28,10 +28,10 @@ HASH_ALGO_MD5, HASH_ALGO_SHA1, HASH_ALGO_RIPE_MD_160, - HASH_ALGO_SHA224, HASH_ALGO_SHA256, HASH_ALGO_SHA384, HASH_ALGO_SHA512, + HASH_ALGO_SHA224, HASH_ALGO_RIPE_MD_128, HASH_ALGO_RIPE_MD_256, HASH_ALGO_RIPE_MD_320, @@ -41,6 +41,12 @@ HASH_ALGO_TGR_128, HASH_ALGO_TGR_160, HASH_ALGO_TGR_192, + HASH_ALGO_SM3_256, + /* + * The above are exported from the Kernel as + * /usr/include/linux/hash_info.h and thus have a fixed number, do not + * change it. Below are barebox specific, subject to renumbering. + */ HASH_ALGO_CRC32, HASH_ALGO__LAST }; diff --git a/lib/kfifo.c b/lib/kfifo.c index 307dae1..fa22feb 100644 --- a/lib/kfifo.c +++ b/lib/kfifo.c @@ -18,6 +18,7 @@ #include #include #include +#include /** * kfifo_init - allocates a new FIFO using a preallocated buffer @@ -49,6 +50,15 @@ unsigned char *buffer; struct kfifo *fifo; + /* + * round up to the next power of 2, since our 'let the indices + * wrap' tachnique works only in this case. + */ + if (size & (size - 1)) { + BUG_ON(size > 0x80000000); + size = roundup_pow_of_two(size); + } + buffer = malloc(size); if (!buffer) return NULL; diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 48ad493..9a6f6e2 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -330,7 +330,7 @@ my @tree_check = ( "arch", "commands", "common", "COPYING", "defaultenv", "Documentation", "drivers", "fs", "include", "lib", - "MAKEALL", "Makefile", "net", "README", "scripts", "TODO" + "MAKEALL", "Makefile", "net", "README", "scripts" ); foreach my $check (@tree_check) {