@@ -323,7 +323,9 @@ GopFramebufferStatus gopfb_validate(
323323 }
324324
325325 if (((handoff -> flags & ~GOPFB_KNOWN_FLAGS ) != GOPFB_U32_C (0 )) ||
326- ((handoff -> flags & GOPFB_FLAG_READY_TO_BOOT ) == GOPFB_U32_C (0 )) ||
326+ ((handoff -> flags & GOPFB_CAPTURE_PHASE_FLAGS ) == GOPFB_U32_C (0 )) ||
327+ ((handoff -> flags & GOPFB_CAPTURE_PHASE_FLAGS ) ==
328+ GOPFB_CAPTURE_PHASE_FLAGS ) ||
327329 ((handoff -> flags & GOPFB_FLAG_MODE_REAPPLIED ) == GOPFB_U32_C (0 ))) {
328330 return GOPFB_STATUS_BAD_FLAGS ;
329331 }
@@ -411,6 +413,157 @@ const char *gopfb_status_string(GopFramebufferStatus status) {
411413 }
412414}
413415
416+ void gopfb_initialize_pci_info (GopFramebufferPciInfo * pciInfo ) {
417+ GopFbSize index ;
418+ GopFbUint8 * bytes ;
419+
420+ if (pciInfo == NULL ) {
421+ return ;
422+ }
423+
424+ bytes = (GopFbUint8 * )pciInfo ;
425+ for (index = 0U ; index < sizeof (* pciInfo ); ++ index ) {
426+ bytes [index ] = GOPFB_U8_C (0 );
427+ }
428+
429+ pciInfo -> magic = GOPFB_PCI_INFO_MAGIC ;
430+ pciInfo -> version = GOPFB_PCI_INFO_VERSION ;
431+ pciInfo -> headerSize =
432+ (GopFbUint16 )GOPFB_OFFSET_OF (GopFramebufferPciInfo , reserved );
433+ pciInfo -> totalSize = (GopFbUint32 )sizeof (* pciInfo );
434+ pciInfo -> barIndex = GOPFB_PCI_INVALID_BAR_INDEX ;
435+ }
436+
437+ void gopfb_finalize_pci_info (GopFramebufferPciInfo * pciInfo ) {
438+ if (pciInfo == NULL ) {
439+ return ;
440+ }
441+
442+ pciInfo -> crc32 = gopfb_crc32 (
443+ pciInfo ,
444+ GOPFB_OFFSET_OF (GopFramebufferPciInfo , crc32 ));
445+ }
446+
447+ GopFramebufferPciInfoStatus gopfb_validate_pci_info (
448+ const GopFramebufferPciInfo * pciInfo ) {
449+ GopFbSize index ;
450+
451+ if (pciInfo == NULL ) {
452+ return GOPFB_PCI_STATUS_NULL ;
453+ }
454+ if (pciInfo -> magic != GOPFB_PCI_INFO_MAGIC ) {
455+ return GOPFB_PCI_STATUS_BAD_MAGIC ;
456+ }
457+ if (pciInfo -> version != GOPFB_PCI_INFO_VERSION ) {
458+ return GOPFB_PCI_STATUS_BAD_VERSION ;
459+ }
460+ if ((pciInfo -> headerSize !=
461+ (GopFbUint16 )GOPFB_OFFSET_OF (GopFramebufferPciInfo , reserved )) ||
462+ (pciInfo -> totalSize != (GopFbUint32 )sizeof (* pciInfo ))) {
463+ return GOPFB_PCI_STATUS_BAD_STRUCTURE_SIZE ;
464+ }
465+ for (index = 0U ;
466+ index < (sizeof (pciInfo -> reserved ) / sizeof (pciInfo -> reserved [0 ]));
467+ ++ index ) {
468+ if (pciInfo -> reserved [index ] != GOPFB_U32_C (0 )) {
469+ return GOPFB_PCI_STATUS_RESERVED_NOT_ZERO ;
470+ }
471+ }
472+ if (pciInfo -> crc32 !=
473+ gopfb_crc32 (
474+ pciInfo ,
475+ GOPFB_OFFSET_OF (GopFramebufferPciInfo , crc32 ))) {
476+ return GOPFB_PCI_STATUS_BAD_CHECKSUM ;
477+ }
478+ if ((pciInfo -> flags & ~GOPFB_PCI_KNOWN_FLAGS ) != GOPFB_U32_C (0 )) {
479+ return GOPFB_PCI_STATUS_BAD_FLAGS ;
480+ }
481+
482+ if ((pciInfo -> flags & GOPFB_PCI_FLAG_LOCATION_VALID ) != GOPFB_U32_C (0 )) {
483+ if ((pciInfo -> segment > GOPFB_U32_C (0xFFFF )) ||
484+ (pciInfo -> bus > GOPFB_U32_C (0xFF )) ||
485+ (pciInfo -> device > GOPFB_U32_C (0x1F )) ||
486+ (pciInfo -> function > GOPFB_U32_C (0x07 ))) {
487+ return GOPFB_PCI_STATUS_BAD_LOCATION ;
488+ }
489+ } else if ((pciInfo -> segment != GOPFB_U32_C (0 )) ||
490+ (pciInfo -> bus != GOPFB_U32_C (0 )) ||
491+ (pciInfo -> device != GOPFB_U32_C (0 )) ||
492+ (pciInfo -> function != GOPFB_U32_C (0 ))) {
493+ return GOPFB_PCI_STATUS_BAD_LOCATION ;
494+ }
495+
496+ if ((pciInfo -> flags & GOPFB_PCI_FLAG_IDENTITY_VALID ) != GOPFB_U32_C (0 )) {
497+ if ((pciInfo -> vendorId == GOPFB_U32_C (0 )) ||
498+ (pciInfo -> vendorId > GOPFB_U32_C (0xFFFF )) ||
499+ (pciInfo -> vendorId == GOPFB_U32_C (0xFFFF )) ||
500+ (pciInfo -> deviceId > GOPFB_U32_C (0xFFFF )) ||
501+ (pciInfo -> deviceId == GOPFB_U32_C (0xFFFF ))) {
502+ return GOPFB_PCI_STATUS_BAD_IDENTITY ;
503+ }
504+ } else if ((pciInfo -> vendorId != GOPFB_U32_C (0 )) ||
505+ (pciInfo -> deviceId != GOPFB_U32_C (0 ))) {
506+ return GOPFB_PCI_STATUS_BAD_IDENTITY ;
507+ }
508+
509+ if ((pciInfo -> flags & GOPFB_PCI_FLAG_CLASS_VALID ) != GOPFB_U32_C (0 )) {
510+ if ((pciInfo -> classCode == GOPFB_U32_C (0 )) ||
511+ (pciInfo -> classCode > GOPFB_U32_C (0x00FFFFFF ))) {
512+ return GOPFB_PCI_STATUS_BAD_CLASS ;
513+ }
514+ } else if (pciInfo -> classCode != GOPFB_U32_C (0 )) {
515+ return GOPFB_PCI_STATUS_BAD_CLASS ;
516+ }
517+
518+ if ((pciInfo -> flags & GOPFB_PCI_FLAG_BAR_VALID ) != GOPFB_U32_C (0 )) {
519+ if ((pciInfo -> barIndex > GOPFB_U32_C (5 )) ||
520+ (pciInfo -> barBase == GOPFB_U64_C (0 )) ||
521+ (pciInfo -> barSize == GOPFB_U64_C (0 )) ||
522+ (pciInfo -> barBase > (GOPFB_U64_MAX - pciInfo -> barSize )) ||
523+ (pciInfo -> framebufferOffset >= pciInfo -> barSize )) {
524+ return GOPFB_PCI_STATUS_BAD_BAR ;
525+ }
526+ } else if ((pciInfo -> barIndex != GOPFB_PCI_INVALID_BAR_INDEX ) ||
527+ (pciInfo -> barBase != GOPFB_U64_C (0 )) ||
528+ (pciInfo -> barSize != GOPFB_U64_C (0 )) ||
529+ (pciInfo -> framebufferOffset != GOPFB_U64_C (0 ))) {
530+ return GOPFB_PCI_STATUS_BAD_BAR ;
531+ }
532+
533+ return GOPFB_PCI_STATUS_OK ;
534+ }
535+
536+ const char * gopfb_pci_status_string (GopFramebufferPciInfoStatus status ) {
537+ switch (status ) {
538+ case GOPFB_PCI_STATUS_OK :
539+ return "ok" ;
540+ case GOPFB_PCI_STATUS_NULL :
541+ return "null input" ;
542+ case GOPFB_PCI_STATUS_BAD_MAGIC :
543+ return "bad magic" ;
544+ case GOPFB_PCI_STATUS_BAD_VERSION :
545+ return "unsupported version" ;
546+ case GOPFB_PCI_STATUS_BAD_STRUCTURE_SIZE :
547+ return "bad structure size" ;
548+ case GOPFB_PCI_STATUS_RESERVED_NOT_ZERO :
549+ return "reserved field is not zero" ;
550+ case GOPFB_PCI_STATUS_BAD_CHECKSUM :
551+ return "bad checksum" ;
552+ case GOPFB_PCI_STATUS_BAD_FLAGS :
553+ return "bad flags" ;
554+ case GOPFB_PCI_STATUS_BAD_LOCATION :
555+ return "bad PCI location" ;
556+ case GOPFB_PCI_STATUS_BAD_IDENTITY :
557+ return "bad PCI identity" ;
558+ case GOPFB_PCI_STATUS_BAD_CLASS :
559+ return "bad PCI class code" ;
560+ case GOPFB_PCI_STATUS_BAD_BAR :
561+ return "bad PCI BAR metadata" ;
562+ default :
563+ return "unknown PCI info status" ;
564+ }
565+ }
566+
414567GopFramebufferEdidStatus gopfb_validate_edid (
415568 const GopFbUint8 * edid ,
416569 GopFbSize edidSize ) {
@@ -429,6 +582,7 @@ GopFramebufferEdidStatus gopfb_validate_edid(
429582
430583 if ((edid == NULL ) ||
431584 (edidSize < (GopFbSize )GOPFB_EDID_BLOCK_SIZE ) ||
585+ (edidSize > (GopFbSize )GOPFB_EDID_MAX_SIZE ) ||
432586 ((edidSize % (GopFbSize )GOPFB_EDID_BLOCK_SIZE ) != 0U )) {
433587 return GOPFB_EDID_STATUS_BAD_SIZE ;
434588 }
@@ -537,7 +691,6 @@ GopFramebufferDisplayInfoStatus gopfb_validate_display_info(
537691 GopFbSize expectedEdidOffset ;
538692 GopFbSize expectedTotalSize ;
539693 GopFbSize index ;
540- GopFbSize otherIndex ;
541694 GopFramebufferEdidStatus edidStatus ;
542695
543696 if (modes != NULL ) {
@@ -592,6 +745,10 @@ GopFramebufferDisplayInfoStatus gopfb_validate_display_info(
592745 return GOPFB_DISPLAY_STATUS_BAD_FLAGS ;
593746 }
594747
748+ if (header -> modeCount > GOPFB_MODE_CATALOG_MAX_COUNT ) {
749+ return GOPFB_DISPLAY_STATUS_TOO_MANY_MODES ;
750+ }
751+
595752 if ((header -> modeCount == GOPFB_U32_C (0 )) ||
596753 !gopfb_size_multiply (
597754 (GopFbSize )header -> modeCount ,
@@ -626,13 +783,16 @@ GopFramebufferDisplayInfoStatus gopfb_validate_display_info(
626783 return GOPFB_DISPLAY_STATUS_INVALID_MODE ;
627784 }
628785
629- for ( otherIndex = index + 1U ;
630- otherIndex < ( GopFbSize ) header -> modeCount ;
631- ++ otherIndex ) {
632- if ( modeArray [ index ]. modeNumber ==
633- modeArray [otherIndex ].modeNumber ) {
786+ if ( index != 0U ) {
787+ const GopFbUint32 previousModeNumber =
788+ modeArray [ index - 1U ]. modeNumber ;
789+
790+ if ( previousModeNumber == modeArray [index ].modeNumber ) {
634791 return GOPFB_DISPLAY_STATUS_DUPLICATE_MODE_NUMBER ;
635792 }
793+ if (previousModeNumber > modeArray [index ].modeNumber ) {
794+ return GOPFB_DISPLAY_STATUS_NON_CANONICAL_MODE_ORDER ;
795+ }
636796 }
637797 }
638798
@@ -682,10 +842,14 @@ const char *gopfb_display_status_string(
682842 return "bad flags" ;
683843 case GOPFB_DISPLAY_STATUS_BAD_LAYOUT :
684844 return "bad variable layout" ;
845+ case GOPFB_DISPLAY_STATUS_TOO_MANY_MODES :
846+ return "mode catalog exceeds defensive limit" ;
685847 case GOPFB_DISPLAY_STATUS_BAD_CURRENT_MODE :
686848 return "bad current mode index" ;
687849 case GOPFB_DISPLAY_STATUS_DUPLICATE_MODE_NUMBER :
688850 return "duplicate mode number" ;
851+ case GOPFB_DISPLAY_STATUS_NON_CANONICAL_MODE_ORDER :
852+ return "mode numbers are not strictly increasing" ;
689853 case GOPFB_DISPLAY_STATUS_INVALID_MODE :
690854 return "invalid mode descriptor" ;
691855 case GOPFB_DISPLAY_STATUS_INVALID_EDID :
0 commit comments