aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMasahisa Kojima <masahisa.kojima@linaro.org>2023-11-10 13:25:41 +0900
committerIlias Apalodimas <ilias.apalodimas@linaro.org>2023-11-18 10:08:09 +0200
commitf01c961ee34c0124ce53020970ba11b0ab316d9e (patch)
tree38de0a4be61040fc610c4fa5eb93fb62fb70da6a
parentd7d07a8b508bb8af564f6de1ea763be0f67f2456 (diff)
downloadu-boot-f01c961ee34c0124ce53020970ba11b0ab316d9e.zip
u-boot-f01c961ee34c0124ce53020970ba11b0ab316d9e.tar.gz
u-boot-f01c961ee34c0124ce53020970ba11b0ab316d9e.tar.bz2
cmd: efidebug: add uri device path
This adds the URI device path option for 'boot add' subcommand. User can add the URI load option for downloading ISO image file or EFI application through network. Currently HTTP is only supported. Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org> Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
-rw-r--r--cmd/efidebug.c78
-rw-r--r--include/net.h8
-rw-r--r--net/wget.c71
3 files changed, 157 insertions, 0 deletions
diff --git a/cmd/efidebug.c b/cmd/efidebug.c
index 201531a..78ef16f 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 61f9018..ac511ea 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 2087146..6ae2237 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;
+}