@@ -610,6 +610,7 @@ SmmEndOfS3ResumeHandler (
610
610
@param[in] Size2 Size of Buff2
611
611
612
612
@retval TRUE Buffers overlap in memory.
613
+ @retval TRUE Math error. Prevents potential math over and underflows.
613
614
@retval FALSE Buffer doesn't overlap.
614
615
615
616
**/
@@ -621,11 +622,24 @@ InternalIsBufferOverlapped (
621
622
IN UINTN Size2
622
623
)
623
624
{
625
+ UINTN End1 ;
626
+ UINTN End2 ;
627
+ BOOLEAN IsOverUnderflow1 ;
628
+ BOOLEAN IsOverUnderflow2 ;
629
+
630
+ // Check for over or underflow
631
+ IsOverUnderflow1 = EFI_ERROR (SafeUintnAdd ((UINTN )Buff1 , Size1 , & End1 ));
632
+ IsOverUnderflow2 = EFI_ERROR (SafeUintnAdd ((UINTN )Buff2 , Size2 , & End2 ));
633
+
634
+ if (IsOverUnderflow1 || IsOverUnderflow2 ) {
635
+ return TRUE;
636
+ }
637
+
624
638
//
625
639
// If buff1's end is less than the start of buff2, then it's ok.
626
640
// Also, if buff1's start is beyond buff2's end, then it's ok.
627
641
//
628
- if ((( Buff1 + Size1 ) <= Buff2 ) || (Buff1 >= ( Buff2 + Size2 ) )) {
642
+ if ((End1 <= ( UINTN ) Buff2 ) || (( UINTN ) Buff1 >= End2 )) {
629
643
return FALSE;
630
644
}
631
645
@@ -651,6 +665,7 @@ SmmEntryPoint (
651
665
EFI_SMM_COMMUNICATE_HEADER * CommunicateHeader ;
652
666
BOOLEAN InLegacyBoot ;
653
667
BOOLEAN IsOverlapped ;
668
+ BOOLEAN IsOverUnderflow ;
654
669
VOID * CommunicationBuffer ;
655
670
UINTN BufferSize ;
656
671
@@ -699,23 +714,31 @@ SmmEntryPoint (
699
714
(UINT8 * )gSmmCorePrivate ,
700
715
sizeof (* gSmmCorePrivate )
701
716
);
702
- if (!SmmIsBufferOutsideSmmValid ((UINTN )CommunicationBuffer , BufferSize ) || IsOverlapped ) {
717
+ //
718
+ // Check for over or underflows
719
+ //
720
+ IsOverUnderflow = EFI_ERROR (SafeUintnSub (BufferSize , OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER , Data ), & BufferSize ));
721
+
722
+ if (!SmmIsBufferOutsideSmmValid ((UINTN )CommunicationBuffer , BufferSize ) ||
723
+ IsOverlapped || IsOverUnderflow )
724
+ {
703
725
//
704
726
// If CommunicationBuffer is not in valid address scope,
705
727
// or there is overlap between gSmmCorePrivate and CommunicationBuffer,
728
+ // or there is over or underflow,
706
729
// return EFI_INVALID_PARAMETER
707
730
//
708
731
gSmmCorePrivate -> CommunicationBuffer = NULL ;
709
732
gSmmCorePrivate -> ReturnStatus = EFI_ACCESS_DENIED ;
710
733
} else {
711
734
CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER * )CommunicationBuffer ;
712
- BufferSize -= OFFSET_OF ( EFI_SMM_COMMUNICATE_HEADER , Data );
713
- Status = SmiManage (
714
- & CommunicateHeader -> HeaderGuid ,
715
- NULL ,
716
- CommunicateHeader -> Data ,
717
- & BufferSize
718
- );
735
+ // BufferSize was updated by the SafeUintnSub() call above.
736
+ Status = SmiManage (
737
+ & CommunicateHeader -> HeaderGuid ,
738
+ NULL ,
739
+ CommunicateHeader -> Data ,
740
+ & BufferSize
741
+ );
719
742
//
720
743
// Update CommunicationBuffer, BufferSize and ReturnStatus
721
744
// Communicate service finished, reset the pointer to CommBuffer to NULL
0 commit comments