loader: efi devpath api usage should be more aware of NULL pointers

As the efi_devpath_last_node() and efi_devpath_trim() can return NULL
pointers, the consumers of this API should check the the NULL pointers.

Same for efinet_dev_init() using calloc().

Reported by:	Robert Mustacchi <rm@joyent.com>
Reviewed by:	jhb, allanjude
Approved by:	allanjude (mentor)
Differential Revision:	https://reviews.freebsd.org/D9203
This commit is contained in:
Toomas Soome 2017-01-18 08:18:07 +00:00
parent 18e367f4aa
commit 9c1cd3f5c3
3 changed files with 32 additions and 16 deletions

View File

@ -106,15 +106,18 @@ efi_devpath_trim(EFI_DEVICE_PATH *devpath)
EFI_DEVICE_PATH *node, *copy;
size_t prefix, len;
node = efi_devpath_last_node(devpath);
if ((node = efi_devpath_last_node(devpath)) == NULL)
return (NULL);
prefix = (UINT8 *)node - (UINT8 *)devpath;
if (prefix == 0)
return (NULL);
len = prefix + DevicePathNodeLength(NextDevicePathNode(node));
copy = malloc(len);
memcpy(copy, devpath, prefix);
node = (EFI_DEVICE_PATH *)((UINT8 *)copy + prefix);
SetDevicePathEndNode(node);
if (copy != NULL) {
memcpy(copy, devpath, prefix);
node = (EFI_DEVICE_PATH *)((UINT8 *)copy + prefix);
SetDevicePathEndNode(node);
}
return (copy);
}

View File

@ -291,12 +291,18 @@ efinet_dev_init()
if (EFI_ERROR(status))
return (efi_status_to_errno(status));
handles2 = (EFI_HANDLE *)malloc(sz);
if (handles2 == NULL) {
free(handles);
return (ENOMEM);
}
nifs = 0;
for (i = 0; i < sz / sizeof(EFI_HANDLE); i++) {
devpath = efi_lookup_devpath(handles[i]);
if (devpath == NULL)
continue;
node = efi_devpath_last_node(devpath);
if ((node = efi_devpath_last_node(devpath)) == NULL)
continue;
if (DevicePathType(node) != MESSAGING_DEVICE_PATH ||
DevicePathSubType(node) != MSG_MAC_ADDR_DP)
continue;
@ -318,20 +324,24 @@ efinet_dev_init()
}
free(handles);
if (nifs == 0) {
free(handles2);
return (ENOENT);
err = ENOENT;
goto done;
}
err = efi_register_handles(&efinet_dev, handles2, NULL, nifs);
if (err != 0) {
free(handles2);
return (err);
}
if (err != 0)
goto done;
efinetif.netif_nifs = nifs;
efinetif.netif_ifs = calloc(nifs, sizeof(struct netif_dif));
stats = calloc(nifs, sizeof(struct netif_stats));
if (efinetif.netif_ifs == NULL || stats == NULL) {
free(efinetif.netif_ifs);
free(stats);
efinetif.netif_ifs = NULL;
err = ENOMEM;
goto done;
}
efinetif.netif_nifs = nifs;
for (i = 0; i < nifs; i++) {
@ -341,9 +351,9 @@ efinet_dev_init()
dif->dif_stats = &stats[i];
dif->dif_private = handles2[i];
}
done:
free(handles2);
return (0);
return (err);
}
static int

View File

@ -130,10 +130,13 @@ efipart_init(void)
* we try to find the parent device and add that instead as
* that will be the CD filesystem.
*/
node = efi_devpath_last_node(devpath);
if ((node = efi_devpath_last_node(devpath)) == NULL)
continue;
if (DevicePathType(node) == MEDIA_DEVICE_PATH &&
DevicePathSubType(node) == MEDIA_CDROM_DP) {
devpathcpy = efi_devpath_trim(devpath);
if (devpathcpy == NULL)
continue;
tmpdevpath = devpathcpy;
status = BS->LocateDevicePath(&blkio_guid, &tmpdevpath,
&handle);