summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2015-07-07 18:44:27 +0000
committeremaste <emaste@FreeBSD.org>2015-07-07 18:44:27 +0000
commit6ee39a4cd824e81d9be1c1f59cff7ae0aaf45c25 (patch)
treee3083fb3ebad7ed5a5c5d3580ab61e56ba81fd16 /sys/boot
parent842e128ace653e59af26fe83a53317c3dbbf9adb (diff)
downloadFreeBSD-src-6ee39a4cd824e81d9be1c1f59cff7ae0aaf45c25.zip
FreeBSD-src-6ee39a4cd824e81d9be1c1f59cff7ae0aaf45c25.tar.gz
Avoid creating invalid UEFI device path
The UEFI loader on the 10.1 release install disk (disc1) modifies an existing EFI_DEVICE_PATH_PROTOCOL instance in an apparent attempt to truncate the device path. In doing so it creates an invalid device path. Perform the equivalent action without modification of structures allocated by firmware. PR: 197641 MFC After: 1 week Submitted by: Chris Ruffin <chris.ruffin@intel.com>
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/efi/libefi/efipart.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/sys/boot/efi/libefi/efipart.c b/sys/boot/efi/libefi/efipart.c
index 13dc0ac..0831a98 100644
--- a/sys/boot/efi/libefi/efipart.c
+++ b/sys/boot/efi/libefi/efipart.c
@@ -63,13 +63,14 @@ static int
efipart_init(void)
{
EFI_BLOCK_IO *blkio;
- EFI_DEVICE_PATH *devpath, *node;
+ EFI_DEVICE_PATH *devpath, *devpathcpy, *tmpdevpath, *node;
EFI_HANDLE *hin, *hout, *aliases, handle;
EFI_STATUS status;
UINTN sz;
CHAR16 *path;
u_int n, nin, nout;
int err;
+ size_t devpathlen;
sz = 0;
hin = NULL;
@@ -98,9 +99,15 @@ efipart_init(void)
if (EFI_ERROR(status)) {
continue;
}
+
node = devpath;
- while (!IsDevicePathEnd(NextDevicePathNode(node)))
+ devpathlen = DevicePathNodeLength(node);
+ while (!IsDevicePathEnd(NextDevicePathNode(node))) {
node = NextDevicePathNode(node);
+ devpathlen += DevicePathNodeLength(node);
+ }
+ devpathlen += DevicePathNodeLength(NextDevicePathNode(node));
+
status = BS->HandleProtocol(hin[n], &blkio_guid,
(void**)&blkio);
if (EFI_ERROR(status))
@@ -117,10 +124,16 @@ efipart_init(void)
*/
if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
DevicePathSubType(node) == MEDIA_CDROM_DP) {
- node->Type = END_DEVICE_PATH_TYPE;
- node->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
- status = BS->LocateDevicePath(&blkio_guid, &devpath,
+ devpathcpy = malloc(devpathlen);
+ memcpy(devpathcpy, devpath, devpathlen);
+ node = devpathcpy;
+ while (!IsDevicePathEnd(NextDevicePathNode(node)))
+ node = NextDevicePathNode(node);
+ SetDevicePathEndNode(node);
+ tmpdevpath = devpathcpy;
+ status = BS->LocateDevicePath(&blkio_guid, &tmpdevpath,
&handle);
+ free(devpathcpy);
if (EFI_ERROR(status))
continue;
hout[nout] = handle;
OpenPOWER on IntegriCloud