diff options
| -rw-r--r-- | cmd/efidebug.c | 78 | ||||
| -rw-r--r-- | include/net.h | 8 | ||||
| -rw-r--r-- | net/wget.c | 71 |
3 files changed, 157 insertions, 0 deletions
diff --git a/cmd/efidebug.c b/cmd/efidebug.c index 201531ac19f..78ef16f4cb5 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -19,6 +19,7 @@ #include <log.h> #include <malloc.h> #include <mapmem.h> +#include <net.h> #include <part.h> #include <search.h> #include <linux/ctype.h> @@ -708,6 +709,65 @@ out: } /** + * efi_boot_add_uri() - set URI load option + * + * @argc: Number of arguments + * @argv: Argument array + * @var_name16: variable name buffer + * @var_name16_size: variable name buffer size + * @lo: pointer to the load option + * @file_path: buffer to set the generated device path pointer + * @fp_size: file_path size + * Return: CMD_RET_SUCCESS on success, + * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure + */ +static int efi_boot_add_uri(int argc, char *const argv[], u16 *var_name16, + size_t var_name16_size, struct efi_load_option *lo, + struct efi_device_path **file_path, + efi_uintn_t *fp_size) +{ + int id; + char *pos; + char *endp; + u16 *label; + efi_uintn_t uridp_len; + struct efi_device_path_uri *uridp; + + if (argc < 3 || lo->label) + return CMD_RET_USAGE; + + id = (int)hextoul(argv[1], &endp); + if (*endp != '\0' || id > 0xffff) + return CMD_RET_USAGE; + + label = efi_convert_string(argv[2]); + if (!label) + return CMD_RET_FAILURE; + + if (!wget_validate_uri(argv[3])) { + printf("ERROR: invalid URI\n"); + return CMD_RET_FAILURE; + } + + efi_create_indexed_name(var_name16, var_name16_size, "Boot", id); + lo->label = label; + + uridp_len = sizeof(struct efi_device_path) + strlen(argv[3]) + 1; + uridp = efi_alloc(uridp_len + sizeof(END)); + uridp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; + uridp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_URI; + uridp->dp.length = uridp_len; + strcpy(uridp->uri, argv[3]); + pos = (char *)uridp + uridp_len; + memcpy(pos, &END, sizeof(END)); + + *file_path = &uridp->dp; + *fp_size += uridp_len + sizeof(END); + + return CMD_RET_SUCCESS; +} + +/** * do_efi_boot_add() - set UEFI load option * * @cmdtp: Command table @@ -829,6 +889,21 @@ static int do_efi_boot_add(struct cmd_tbl *cmdtp, int flag, argc -= 1; argv += 1; break; + case 'u': + if (IS_ENABLED(CONFIG_EFI_HTTP_BOOT)) { + r = efi_boot_add_uri(argc, argv, var_name16, + sizeof(var_name16), &lo, + &file_path, &fp_size); + if (r != CMD_RET_SUCCESS) + goto out; + fp_free = file_path; + argc -= 3; + argv += 3; + } else{ + r = CMD_RET_USAGE; + goto out; + } + break; default: r = CMD_RET_USAGE; goto out; @@ -1491,6 +1566,9 @@ U_BOOT_LONGHELP(efidebug, " -b|-B <bootid> <label> <interface> <devnum>[:<part>] <file path>\n" " -i|-I <interface> <devnum>[:<part>] <initrd file path>\n" " (-b, -i for short form device path)\n" +#if (IS_ENABLED(CONFIG_EFI_HTTP_BOOT)) + " -u <bootid> <label> <uri>\n" +#endif " -s '<optional data>'\n" "efidebug boot rm <bootid#1> [<bootid#2> [<bootid#3> [...]]]\n" " - delete UEFI BootXXXX variables\n" diff --git a/include/net.h b/include/net.h index 61f9018769a..ac511eab103 100644 --- a/include/net.h +++ b/include/net.h @@ -939,4 +939,12 @@ static inline void eth_set_enable_bootdevs(bool enable) {} */ int wget_with_dns(ulong dst_addr, char *uri); +/** + * wget_validate_uri() - varidate the uri + * + * @uri: uri string of target file of wget + * Return: true if uri is valid, false if uri is invalid + */ +bool wget_validate_uri(char *uri); + #endif /* __NET_H__ */ diff --git a/net/wget.c b/net/wget.c index 2087146b377..6ae2237a0a8 100644 --- a/net/wget.c +++ b/net/wget.c @@ -566,3 +566,74 @@ out: return ret; } #endif + +/** + * wget_validate_uri() - validate the uri for wget + * + * @uri: uri string + * + * This function follows the current U-Boot wget implementation. + * scheme: only "http:" is supported + * authority: + * - user information: not supported + * - host: supported + * - port: not supported(always use the default port) + * + * Uri is expected to be correctly percent encoded. + * This is the minimum check, control codes(0x1-0x19, 0x7F, except '\0') + * and space character(0x20) are not allowed. + * + * TODO: stricter uri conformance check + * + * Return: true on success, false on failure + */ +bool wget_validate_uri(char *uri) +{ + char c; + bool ret = true; + char *str_copy, *s, *authority; + + for (c = 0x1; c < 0x21; c++) { + if (strchr(uri, c)) { + log_err("invalid character is used\n"); + return false; + } + } + if (strchr(uri, 0x7f)) { + log_err("invalid character is used\n"); + return false; + } + + if (strncmp(uri, "http://", 7)) { + log_err("only http:// is supported\n"); + return false; + } + str_copy = strdup(uri); + if (!str_copy) + return false; + + s = str_copy + strlen("http://"); + authority = strsep(&s, "/"); + if (!s) { + log_err("invalid uri, no file path\n"); + ret = false; + goto out; + } + s = strchr(authority, '@'); + if (s) { + log_err("user information is not supported\n"); + ret = false; + goto out; + } + s = strchr(authority, ':'); + if (s) { + log_err("user defined port is not supported\n"); + ret = false; + goto out; + } + +out: + free(str_copy); + + return ret; +} |
