Skip to content

Commit f62dcb5

Browse files
committed
lib: fatlib: Avoid unaligned access to LFN name fields
GCC 9 now starts emitting warnings (turned errors) because we grab the address of the Long File Name FAT directory entries, which are PUSHORTs, but are not aligned. We then access those pointers as an array. We do (at least in all cases that mattered) use the READ_UNALIGNED16() macro, but GCC isn't smart enough to see that we're careful with how we use the pointer. To fix, convert to a char pointer, and access with care, as before. Also, FAT_DIRECTORY_ENTRY structures are always aligned to 32-byte boundaries, so mark their structs as such if it helps with other fields.
1 parent 9e489f6 commit f62dcb5

File tree

4 files changed

+37
-35
lines changed

4 files changed

+37
-35
lines changed

boot/fatboot/fatboot.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ Return Value:
863863
PFAT_LONG_DIRECTORY_ENTRY LongEntry;
864864
UCHAR LongEntryChecksum;
865865
ULONG NameIndex;
866-
PUSHORT Region;
866+
PUCHAR Region;
867867
ULONG RegionIndex;
868868
ULONG RegionSize;
869869
UCHAR Sequence;
@@ -896,27 +896,29 @@ Return Value:
896896
NameIndex = *State;
897897
for (RegionIndex = 0; RegionIndex < 3; RegionIndex += 1) {
898898
if (RegionIndex == 0) {
899-
Region = LongEntry->Name1;
900-
RegionSize = FAT_LONG_DIRECTORY_ENTRY_NAME1_SIZE;
899+
Region = (PUCHAR)&(LongEntry->Name1);
900+
RegionSize = sizeof(LongEntry->Name1);
901901

902902
} else if (RegionIndex == 1) {
903-
Region = LongEntry->Name2;
904-
RegionSize = FAT_LONG_DIRECTORY_ENTRY_NAME2_SIZE;
903+
Region = (PUCHAR)&(LongEntry->Name2);
904+
RegionSize = sizeof(LongEntry->Name2);
905905

906906
} else {
907-
Region = LongEntry->Name3;
908-
RegionSize = FAT_LONG_DIRECTORY_ENTRY_NAME3_SIZE;
907+
Region = (PUCHAR)&(LongEntry->Name3);
908+
RegionSize = sizeof(LongEntry->Name3);
909909
}
910910

911911
for (CharacterIndex = 0;
912912
CharacterIndex < RegionSize;
913-
CharacterIndex += 1) {
913+
CharacterIndex += sizeof(USHORT)) {
914914

915915
if (Name[NameIndex] == '\0') {
916916
break;
917917
}
918918

919-
if (Region[CharacterIndex] != Name[NameIndex]) {
919+
if (READ_UNALIGNED16(&(Region[CharacterIndex])) !=
920+
Name[NameIndex]) {
921+
920922
return FALSE;
921923
}
922924

include/minoca/lib/fat/fatlib.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ typedef struct _FAT_DIRECTORY_ENTRY {
551551
USHORT LastModifiedDate;
552552
USHORT ClusterLow;
553553
ULONG FileSizeInBytes;
554-
} PACKED FAT_DIRECTORY_ENTRY, *PFAT_DIRECTORY_ENTRY;
554+
} PACKED ALIGNED32 FAT_DIRECTORY_ENTRY, *PFAT_DIRECTORY_ENTRY;
555555

556556
/*++
557557
@@ -595,7 +595,7 @@ typedef struct _FAT_LONG_DIRECTORY_ENTRY {
595595
USHORT Name2[FAT_LONG_DIRECTORY_ENTRY_NAME2_SIZE];
596596
USHORT Cluster;
597597
USHORT Name3[FAT_LONG_DIRECTORY_ENTRY_NAME3_SIZE];
598-
} PACKED FAT_LONG_DIRECTORY_ENTRY, *PFAT_LONG_DIRECTORY_ENTRY;
598+
} PACKED ALIGNED32 FAT_LONG_DIRECTORY_ENTRY, *PFAT_LONG_DIRECTORY_ENTRY;
599599

600600
#pragma pack(pop)
601601

lib/fatlib/fatsup.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ Return Value:
872872
ULONG RegionIndex;
873873
UCHAR Sequence;
874874
UCHAR ShortNameChecksum;
875-
PUSHORT Source;
875+
PUCHAR Source;
876876
ULONG SourceCount;
877877
ULONG SourceIndex;
878878
ULONG SourceSize;
@@ -981,21 +981,21 @@ Return Value:
981981

982982
for (RegionIndex = 0; RegionIndex < 3; RegionIndex += 1) {
983983
if (RegionIndex == 0) {
984-
Source = LongEntry->Name1;
985-
SourceSize = FAT_LONG_DIRECTORY_ENTRY_NAME1_SIZE;
984+
Source = (PUCHAR)&(LongEntry->Name1);
985+
SourceSize = sizeof(LongEntry->Name1);
986986

987987
} else if (RegionIndex == 1) {
988-
Source = LongEntry->Name2;
989-
SourceSize = FAT_LONG_DIRECTORY_ENTRY_NAME2_SIZE;
988+
Source = (PUCHAR)&(LongEntry->Name2);
989+
SourceSize = sizeof(LongEntry->Name2);
990990

991991
} else {
992-
Source = LongEntry->Name3;
993-
SourceSize = FAT_LONG_DIRECTORY_ENTRY_NAME3_SIZE;
992+
Source = (PUCHAR)&(LongEntry->Name3);
993+
SourceSize = sizeof(LongEntry->Name3);
994994
}
995995

996996
for (SourceIndex = 0;
997997
SourceIndex < SourceSize;
998-
SourceIndex += 1) {
998+
SourceIndex += sizeof(USHORT)) {
999999

10001000
FileName[CharacterIndex] =
10011001
(CHAR)FAT_READ_INT16(&(Source[SourceIndex]));
@@ -3695,7 +3695,7 @@ Return Value:
36953695

36963696
USHORT Character;
36973697
ULONG CharacterIndex;
3698-
PUSHORT Destination;
3698+
PUCHAR Destination;
36993699
ULONG DestinationIndex;
37003700
ULONG DestinationSize;
37013701
PFAT_DIRECTORY_ENTRY Entries;
@@ -4010,21 +4010,21 @@ Return Value:
40104010

40114011
for (RegionIndex = 0; RegionIndex < 3; RegionIndex += 1) {
40124012
if (RegionIndex == 0) {
4013-
Destination = LongEntry->Name1;
4014-
DestinationSize = FAT_LONG_DIRECTORY_ENTRY_NAME1_SIZE;
4013+
Destination = (PUCHAR)&(LongEntry->Name1);
4014+
DestinationSize = sizeof(LongEntry->Name1);
40154015

40164016
} else if (RegionIndex == 1) {
4017-
Destination = LongEntry->Name2;
4018-
DestinationSize = FAT_LONG_DIRECTORY_ENTRY_NAME2_SIZE;
4017+
Destination = (PUCHAR)&(LongEntry->Name2);
4018+
DestinationSize = sizeof(LongEntry->Name2);
40194019

40204020
} else {
4021-
Destination = LongEntry->Name3;
4022-
DestinationSize = FAT_LONG_DIRECTORY_ENTRY_NAME3_SIZE;
4021+
Destination = (PUCHAR)&(LongEntry->Name3);
4022+
DestinationSize = sizeof(LongEntry->Name3);
40234023
}
40244024

40254025
for (DestinationIndex = 0;
40264026
DestinationIndex < DestinationSize;
4027-
DestinationIndex += 1) {
4027+
DestinationIndex += sizeof(USHORT)) {
40284028

40294029
if (CharacterIndex < FileNameLength) {
40304030
Character = FileName[CharacterIndex];

uefi/plat/panda/init/fatboot.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ Return Value:
731731
PFAT_LONG_DIRECTORY_ENTRY LongEntry;
732732
UCHAR LongEntryChecksum;
733733
ULONG NameIndex;
734-
PUSHORT Region;
734+
PUCHAR Region;
735735
ULONG RegionIndex;
736736
ULONG RegionSize;
737737
UCHAR Sequence;
@@ -764,21 +764,21 @@ Return Value:
764764
NameIndex = *State;
765765
for (RegionIndex = 0; RegionIndex < 3; RegionIndex += 1) {
766766
if (RegionIndex == 0) {
767-
Region = LongEntry->Name1;
768-
RegionSize = FAT_LONG_DIRECTORY_ENTRY_NAME1_SIZE;
767+
Region = (PUCHAR)&(LongEntry->Name1);
768+
RegionSize = sizeof(LongEntry->Name1);
769769

770770
} else if (RegionIndex == 1) {
771-
Region = LongEntry->Name2;
772-
RegionSize = FAT_LONG_DIRECTORY_ENTRY_NAME2_SIZE;
771+
Region = (PUCHAR)&(LongEntry->Name2);
772+
RegionSize = sizeof(LongEntry->Name2);
773773

774774
} else {
775-
Region = LongEntry->Name3;
776-
RegionSize = FAT_LONG_DIRECTORY_ENTRY_NAME3_SIZE;
775+
Region = (PUCHAR)&(LongEntry->Name3);
776+
RegionSize = sizeof(LongEntry->Name3);
777777
}
778778

779779
for (CharacterIndex = 0;
780780
CharacterIndex < RegionSize;
781-
CharacterIndex += 1) {
781+
CharacterIndex += sizeof(USHORT)) {
782782

783783
if (Name[NameIndex] == '\0') {
784784
break;

0 commit comments

Comments
 (0)