mirror of
https://github.com/systemd/systemd.git
synced 2026-08-11 01:25:28 +00:00
efi-api: validate boot option device path lengths
efi_get_boot_option() validates the overall Boot#### variable size and the advertised device-path byte count, but then walks each device-path node without first checking that the node header and subtype payload fit in the remaining buffer. A malformed Boot#### variable could make the parser read past the end of the current node, or past the available device-path data. Limit parsing to the bytes that are actually present, and stop walking the device path when a malformed node is encountered. This keeps the previous best-effort behaviour for fields parsed before the anomaly while avoiding out-of-bounds reads. Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com> (cherry picked from commitd13b002aec) (cherry picked from commita955daf063) (cherry picked from commit6cc087b861)
This commit is contained in:
committed by
Luca Boccassi
parent
1d410b0dc9
commit
7dfc8685fe
@@ -283,19 +283,23 @@ int efi_get_boot_option(
|
||||
|
||||
if (header->path_len > 0) {
|
||||
uint8_t *dbuf;
|
||||
size_t dnext, doff;
|
||||
size_t dnext, doff, path_len;
|
||||
|
||||
doff = offsetof(struct boot_option, title) + title_size;
|
||||
dbuf = buf + doff;
|
||||
if (header->path_len > l - doff)
|
||||
return -EINVAL;
|
||||
path_len = MIN((size_t) header->path_len, l - doff);
|
||||
|
||||
dnext = 0;
|
||||
while (dnext < header->path_len) {
|
||||
while (dnext < path_len) {
|
||||
struct device_path *dpath;
|
||||
size_t remaining = path_len - dnext;
|
||||
|
||||
if (remaining < offsetof(struct device_path, path))
|
||||
break;
|
||||
|
||||
dpath = (struct device_path *)(dbuf + dnext);
|
||||
if (dpath->length < 4)
|
||||
if (dpath->length < offsetof(struct device_path, path) ||
|
||||
dpath->length > remaining)
|
||||
break;
|
||||
|
||||
/* Type 0x7F – End of Hardware Device Path, Sub-Type 0xFF – End Entire Device Path */
|
||||
@@ -310,6 +314,9 @@ int efi_get_boot_option(
|
||||
|
||||
/* Sub-Type 1 – Hard Drive */
|
||||
if (dpath->sub_type == MEDIA_HARDDRIVE_DP) {
|
||||
if (dpath->length < offsetof(struct device_path, drive) + sizeof(struct drive_path))
|
||||
break;
|
||||
|
||||
/* 0x02 – GUID Partition Table */
|
||||
if (dpath->drive.mbr_type != MBR_TYPE_EFI_PARTITION_TABLE_HEADER)
|
||||
continue;
|
||||
@@ -325,9 +332,9 @@ int efi_get_boot_option(
|
||||
|
||||
/* Sub-Type 4 – File Path */
|
||||
if (dpath->sub_type == MEDIA_FILEPATH_DP && !p && ret_path) {
|
||||
p = utf16_to_utf8(dpath->path, dpath->length-4);
|
||||
p = utf16_to_utf8(dpath->path, dpath->length - offsetof(struct device_path, path));
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
return -ENOMEM;
|
||||
|
||||
efi_tilt_backslashes(p);
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user