Skip to content

Commit c6c4dd5

Browse files
tatokisalexdeucher
authored andcommitted
drm/amdgpu/pptable: Fix UBSAN array-index-out-of-bounds
Flexible arrays used [1] instead of []. Replace the former with the latter to resolve multiple UBSAN warnings observed on boot with a BONAIRE card. In addition, use the __counted_by attribute where possible to hint the length of the arrays to the compiler and any sanitizers. Signed-off-by: Tasos Sahanidis <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 267cace commit c6c4dd5

File tree

1 file changed

+49
-42
lines changed

1 file changed

+49
-42
lines changed

drivers/gpu/drm/amd/include/pptable.h

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -477,31 +477,30 @@ typedef struct _ATOM_PPLIB_STATE_V2
477477
} ATOM_PPLIB_STATE_V2;
478478

479479
typedef struct _StateArray{
480-
//how many states we have
481-
UCHAR ucNumEntries;
482-
483-
ATOM_PPLIB_STATE_V2 states[1];
480+
//how many states we have
481+
UCHAR ucNumEntries;
482+
483+
ATOM_PPLIB_STATE_V2 states[] /* __counted_by(ucNumEntries) */;
484484
}StateArray;
485485

486486

487487
typedef struct _ClockInfoArray{
488-
//how many clock levels we have
489-
UCHAR ucNumEntries;
490-
491-
//sizeof(ATOM_PPLIB_CLOCK_INFO)
492-
UCHAR ucEntrySize;
493-
494-
UCHAR clockInfo[];
488+
//how many clock levels we have
489+
UCHAR ucNumEntries;
490+
491+
//sizeof(ATOM_PPLIB_CLOCK_INFO)
492+
UCHAR ucEntrySize;
493+
494+
UCHAR clockInfo[];
495495
}ClockInfoArray;
496496

497497
typedef struct _NonClockInfoArray{
498+
//how many non-clock levels we have. normally should be same as number of states
499+
UCHAR ucNumEntries;
500+
//sizeof(ATOM_PPLIB_NONCLOCK_INFO)
501+
UCHAR ucEntrySize;
498502

499-
//how many non-clock levels we have. normally should be same as number of states
500-
UCHAR ucNumEntries;
501-
//sizeof(ATOM_PPLIB_NONCLOCK_INFO)
502-
UCHAR ucEntrySize;
503-
504-
ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[];
503+
ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[] __counted_by(ucNumEntries);
505504
}NonClockInfoArray;
506505

507506
typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record
@@ -513,8 +512,10 @@ typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record
513512

514513
typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Table
515514
{
516-
UCHAR ucNumEntries; // Number of entries.
517-
ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[1]; // Dynamically allocate entries.
515+
// Number of entries.
516+
UCHAR ucNumEntries;
517+
// Dynamically allocate entries.
518+
ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[] __counted_by(ucNumEntries);
518519
}ATOM_PPLIB_Clock_Voltage_Dependency_Table;
519520

520521
typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Record
@@ -529,8 +530,10 @@ typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Record
529530

530531
typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Table
531532
{
532-
UCHAR ucNumEntries; // Number of entries.
533-
ATOM_PPLIB_Clock_Voltage_Limit_Record entries[1]; // Dynamically allocate entries.
533+
// Number of entries.
534+
UCHAR ucNumEntries;
535+
// Dynamically allocate entries.
536+
ATOM_PPLIB_Clock_Voltage_Limit_Record entries[] __counted_by(ucNumEntries);
534537
}ATOM_PPLIB_Clock_Voltage_Limit_Table;
535538

536539
union _ATOM_PPLIB_CAC_Leakage_Record
@@ -553,8 +556,10 @@ typedef union _ATOM_PPLIB_CAC_Leakage_Record ATOM_PPLIB_CAC_Leakage_Record;
553556

554557
typedef struct _ATOM_PPLIB_CAC_Leakage_Table
555558
{
556-
UCHAR ucNumEntries; // Number of entries.
557-
ATOM_PPLIB_CAC_Leakage_Record entries[1]; // Dynamically allocate entries.
559+
// Number of entries.
560+
UCHAR ucNumEntries;
561+
// Dynamically allocate entries.
562+
ATOM_PPLIB_CAC_Leakage_Record entries[] __counted_by(ucNumEntries);
558563
}ATOM_PPLIB_CAC_Leakage_Table;
559564

560565
typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Record
@@ -568,8 +573,10 @@ typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Record
568573

569574
typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Table
570575
{
571-
UCHAR ucNumEntries; // Number of entries.
572-
ATOM_PPLIB_PhaseSheddingLimits_Record entries[1]; // Dynamically allocate entries.
576+
// Number of entries.
577+
UCHAR ucNumEntries;
578+
// Dynamically allocate entries.
579+
ATOM_PPLIB_PhaseSheddingLimits_Record entries[] __counted_by(ucNumEntries);
573580
}ATOM_PPLIB_PhaseSheddingLimits_Table;
574581

575582
typedef struct _VCEClockInfo{
@@ -580,8 +587,8 @@ typedef struct _VCEClockInfo{
580587
}VCEClockInfo;
581588

582589
typedef struct _VCEClockInfoArray{
583-
UCHAR ucNumEntries;
584-
VCEClockInfo entries[1];
590+
UCHAR ucNumEntries;
591+
VCEClockInfo entries[] __counted_by(ucNumEntries);
585592
}VCEClockInfoArray;
586593

587594
typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record
@@ -592,8 +599,8 @@ typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record
592599

593600
typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table
594601
{
595-
UCHAR numEntries;
596-
ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record entries[1];
602+
UCHAR numEntries;
603+
ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record entries[] __counted_by(numEntries);
597604
}ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table;
598605

599606
typedef struct _ATOM_PPLIB_VCE_State_Record
@@ -604,8 +611,8 @@ typedef struct _ATOM_PPLIB_VCE_State_Record
604611

605612
typedef struct _ATOM_PPLIB_VCE_State_Table
606613
{
607-
UCHAR numEntries;
608-
ATOM_PPLIB_VCE_State_Record entries[1];
614+
UCHAR numEntries;
615+
ATOM_PPLIB_VCE_State_Record entries[] __counted_by(numEntries);
609616
}ATOM_PPLIB_VCE_State_Table;
610617

611618

@@ -626,8 +633,8 @@ typedef struct _UVDClockInfo{
626633
}UVDClockInfo;
627634

628635
typedef struct _UVDClockInfoArray{
629-
UCHAR ucNumEntries;
630-
UVDClockInfo entries[1];
636+
UCHAR ucNumEntries;
637+
UVDClockInfo entries[] __counted_by(ucNumEntries);
631638
}UVDClockInfoArray;
632639

633640
typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record
@@ -638,8 +645,8 @@ typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record
638645

639646
typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table
640647
{
641-
UCHAR numEntries;
642-
ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record entries[1];
648+
UCHAR numEntries;
649+
ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record entries[] __counted_by(numEntries);
643650
}ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table;
644651

645652
typedef struct _ATOM_PPLIB_UVD_Table
@@ -657,8 +664,8 @@ typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Record
657664
}ATOM_PPLIB_SAMClk_Voltage_Limit_Record;
658665

659666
typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Table{
660-
UCHAR numEntries;
661-
ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[];
667+
UCHAR numEntries;
668+
ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[] __counted_by(numEntries);
662669
}ATOM_PPLIB_SAMClk_Voltage_Limit_Table;
663670

664671
typedef struct _ATOM_PPLIB_SAMU_Table
@@ -675,8 +682,8 @@ typedef struct _ATOM_PPLIB_ACPClk_Voltage_Limit_Record
675682
}ATOM_PPLIB_ACPClk_Voltage_Limit_Record;
676683

677684
typedef struct _ATOM_PPLIB_ACPClk_Voltage_Limit_Table{
678-
UCHAR numEntries;
679-
ATOM_PPLIB_ACPClk_Voltage_Limit_Record entries[1];
685+
UCHAR numEntries;
686+
ATOM_PPLIB_ACPClk_Voltage_Limit_Record entries[] __counted_by(numEntries);
680687
}ATOM_PPLIB_ACPClk_Voltage_Limit_Table;
681688

682689
typedef struct _ATOM_PPLIB_ACP_Table
@@ -743,9 +750,9 @@ typedef struct ATOM_PPLIB_VQ_Budgeting_Record{
743750
} ATOM_PPLIB_VQ_Budgeting_Record;
744751

745752
typedef struct ATOM_PPLIB_VQ_Budgeting_Table {
746-
UCHAR revid;
747-
UCHAR numEntries;
748-
ATOM_PPLIB_VQ_Budgeting_Record entries[1];
753+
UCHAR revid;
754+
UCHAR numEntries;
755+
ATOM_PPLIB_VQ_Budgeting_Record entries[] __counted_by(numEntries);
749756
} ATOM_PPLIB_VQ_Budgeting_Table;
750757

751758
#pragma pack()

0 commit comments

Comments
 (0)