diff options
author | Heinrich Schuchardt <heinrich.schuchardt@canonical.com> | 2022-01-29 19:01:07 +0100 |
---|---|---|
committer | Heinrich Schuchardt <heinrich.schuchardt@canonical.com> | 2022-02-05 20:20:01 +0100 |
commit | 344f26a7664f0a3f1a4b302e08a408171bdc3ece (patch) | |
tree | c945592c15b0fc67394ea7c97803549201446f72 /lib | |
parent | c672dd770ee0d9874086543c20a9088124514051 (diff) | |
download | u-boot-344f26a7664f0a3f1a4b302e08a408171bdc3ece.tar.gz u-boot-344f26a7664f0a3f1a4b302e08a408171bdc3ece.tar.bz2 u-boot-344f26a7664f0a3f1a4b302e08a408171bdc3ece.zip |
efi_loader: fix device path to text protocol
The printing of a file path node must properly handle:
* odd length of the device path node
* UTF-16 character only partially contained in device path node
* buffer overflow due to very long file path
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/efi_loader/efi_device_path_to_text.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c index d8a83c8849..97b3d3e815 100644 --- a/lib/efi_loader/efi_device_path_to_text.c +++ b/lib/efi_loader/efi_device_path_to_text.c @@ -8,6 +8,7 @@ #include <common.h> #include <blk.h> #include <efi_loader.h> +#include <malloc.h> #define MAC_OUTPUT_LEN 22 #define UNKNOWN_OUTPUT_LEN 23 @@ -292,10 +293,18 @@ static char *dp_media(char *s, struct efi_device_path *dp) case DEVICE_PATH_SUB_TYPE_FILE_PATH: { struct efi_device_path_file_path *fp = (struct efi_device_path_file_path *)dp; - int slen = (dp->length - sizeof(*dp)) / 2; - if (slen > MAX_NODE_LEN - 2) - slen = MAX_NODE_LEN - 2; - s += sprintf(s, "%-.*ls", slen, fp->str); + u16 *buffer; + int slen = dp->length - sizeof(*dp); + + /* two bytes for \0, extra byte if dp->length is odd */ + buffer = calloc(1, slen + 3); + if (!buffer) { + log_err("Out of memory\n"); + return s; + } + memcpy(buffer, fp->str, dp->length - sizeof(*dp)); + s += snprintf(s, MAX_NODE_LEN - 1, "%ls", buffer); + free(buffer); break; } default: |