Index: shim-0.7.318.81ee561d/MokManager.c =================================================================== --- shim-0.7.318.81ee561d.orig/MokManager.c +++ shim-0.7.318.81ee561d/MokManager.c @@ -163,8 +163,18 @@ static UINT32 count_keys(void *Data, UIN EFI_SIGNATURE_LIST *CertList = Data; UINTN dbsize = DataSize; UINT32 MokNum = 0; + void *end = Data + DataSize; while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) { + + /* Use ptr arithmetics to ensure bounded access. Do not allow 0 + * SignatureListSize that will cause endless loop. + */ + if ((void *)(CertList + 1) > end || CertList->SignatureListSize == 0) { + console_notify(L"Invalid MOK detected! Ignoring MOK List."); + return 0; + } + if (CertList->SignatureListSize == 0 || CertList->SignatureListSize <= CertList->SignatureSize) { console_errorbox(L"Corrupted signature list"); @@ -192,6 +202,7 @@ static MokListNode *build_mok_list(UINT3 EFI_GUID CertType = X509_GUID; UINTN dbsize = DataSize; UINTN count = 0; + void *end = Data + DataSize; list = AllocatePool(sizeof(MokListNode) * num); @@ -201,12 +212,24 @@ static MokListNode *build_mok_list(UINT3 } while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) { + /* CertList out of bounds? */ + if ((void *)(CertList + 1) > end || CertList->SignatureListSize == 0) { + FreePool(list); + return NULL; + } + /* Omit the signature check here since we already did it in count_keys() */ Cert = (EFI_SIGNATURE_DATA *) (((UINT8 *) CertList) + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); + /* Cert out of bounds? */ + if ((void *)(Cert + 1) > end || CertList->SignatureSize <= sizeof(EFI_GUID)) { + FreePool(list); + return NULL; + } + list[count].Type = CertList->SignatureType; if (CompareGuid (&CertList->SignatureType, &CertType) == 0) { list[count].MokSize = CertList->SignatureSize - @@ -218,6 +241,12 @@ static MokListNode *build_mok_list(UINT3 list[count].Mok = (void *)Cert; } + /* MOK out of bounds? */ + if (list[count].MokSize > end - (void *)list[count].Mok) { + FreePool(list); + return NULL; + } + count++; dbsize -= CertList->SignatureListSize; CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList +