TianoCore EDK2 master
Loading...
Searching...
No Matches
StandaloneMmPeCoffExtraActionLib.c
Go to the documentation of this file.
1
11#include <PiDxe.h>
12
13#include <Library/BaseLib.h>
15#include <Library/DebugLib.h>
16#include <Library/PcdLib.h>
17#include <Library/PeCoffLib.h>
20
21typedef RETURN_STATUS (*REGION_PERMISSION_UPDATE_FUNC) (
22 IN EFI_PHYSICAL_ADDRESS BaseAddress,
23 IN UINT64 Length
24 );
25
27RETURN_STATUS
28UpdatePeCoffPermissions (
30 IN REGION_PERMISSION_UPDATE_FUNC NoExecUpdater,
31 IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater
32 )
33{
34 RETURN_STATUS Status;
37 UINTN Size;
38 UINTN ReadSize;
39 UINT32 SectionHeaderOffset;
40 UINTN NumberOfSections;
41 UINTN Index;
42 EFI_IMAGE_SECTION_HEADER SectionHeader;
45
46 //
47 // We need to copy ImageContext since PeCoffLoaderGetImageInfo ()
48 // will mangle the ImageAddress field
49 //
50 CopyMem (&TmpContext, ImageContext, sizeof (TmpContext));
51
52 if (TmpContext.PeCoffHeaderOffset == 0) {
53 Status = PeCoffLoaderGetImageInfo (&TmpContext);
54 if (RETURN_ERROR (Status)) {
55 DEBUG ((
56 DEBUG_ERROR,
57 "%a: PeCoffLoaderGetImageInfo () failed (Status = %r)\n",
58 __func__,
59 Status
60 ));
61 return Status;
62 }
63 }
64
65 if (TmpContext.IsTeImage &&
66 (TmpContext.ImageAddress == ImageContext->ImageAddress))
67 {
68 DEBUG ((
69 DEBUG_INFO,
70 "%a: ignoring XIP TE image at 0x%lx\n",
71 __func__,
72 ImageContext->ImageAddress
73 ));
74 return RETURN_SUCCESS;
75 }
76
77 if (TmpContext.SectionAlignment < EFI_PAGE_SIZE) {
78 //
79 // The sections need to be at least 4 KB aligned, since that is the
80 // granularity at which we can tighten permissions. So just clear the
81 // noexec permissions on the entire region.
82 //
83 if (!TmpContext.IsTeImage) {
84 DEBUG ((
85 DEBUG_WARN,
86 "%a: non-TE Image at 0x%lx has SectionAlignment < 4 KB (%lu)\n",
87 __func__,
88 ImageContext->ImageAddress,
89 TmpContext.SectionAlignment
90 ));
91 }
92
93 Base = ImageContext->ImageAddress & ~(EFI_PAGE_SIZE - 1);
94 Size = ImageContext->ImageAddress - Base + ImageContext->ImageSize;
95 return NoExecUpdater (Base, ALIGN_VALUE (Size, EFI_PAGE_SIZE));
96 }
97
98 //
99 // Read the PE/COFF Header. For PE32 (32-bit) this will read in too much
100 // data, but that should not hurt anything. Hdr.Pe32->OptionalHeader.Magic
101 // determines if this is a PE32 or PE32+ image. The magic is in the same
102 // location in both images.
103 //
104 Hdr.Union = &HdrData;
105 Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
106 ReadSize = Size;
107 Status = TmpContext.ImageRead (
108 TmpContext.Handle,
109 TmpContext.PeCoffHeaderOffset,
110 &Size,
111 Hdr.Pe32
112 );
113 if (RETURN_ERROR (Status) || (Size != ReadSize)) {
114 DEBUG ((
115 DEBUG_ERROR,
116 "%a: TmpContext.ImageRead () failed (Status = %r)\n",
117 __func__,
118 Status
119 ));
120 return Status;
121 }
122
123 ASSERT (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE);
124
125 SectionHeaderOffset = TmpContext.PeCoffHeaderOffset + sizeof (UINT32) +
126 sizeof (EFI_IMAGE_FILE_HEADER);
127 NumberOfSections = (UINTN)(Hdr.Pe32->FileHeader.NumberOfSections);
128
129 switch (Hdr.Pe32->OptionalHeader.Magic) {
131 SectionHeaderOffset += Hdr.Pe32->FileHeader.SizeOfOptionalHeader;
132 break;
134 SectionHeaderOffset += Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader;
135 break;
136 default:
137 ASSERT (FALSE);
138 }
139
140 //
141 // Iterate over the sections
142 //
143 for (Index = 0; Index < NumberOfSections; Index++) {
144 //
145 // Read section header from file
146 //
147 Size = sizeof (EFI_IMAGE_SECTION_HEADER);
148 ReadSize = Size;
149 Status = TmpContext.ImageRead (
150 TmpContext.Handle,
151 SectionHeaderOffset,
152 &Size,
153 &SectionHeader
154 );
155 if (RETURN_ERROR (Status) || (Size != ReadSize)) {
156 DEBUG ((
157 DEBUG_ERROR,
158 "%a: TmpContext.ImageRead () failed (Status = %r)\n",
159 __func__,
160 Status
161 ));
162 return Status;
163 }
164
165 Base = TmpContext.ImageAddress + SectionHeader.VirtualAddress;
166
167 if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) == 0) {
168 if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_WRITE) == 0) {
169 DEBUG ((
170 DEBUG_INFO,
171 "%a: Mapping section %d of image at 0x%lx with RO-XN permissions and size 0x%x\n",
172 __func__,
173 Index,
174 Base,
175 SectionHeader.Misc.VirtualSize
176 ));
177 ReadOnlyUpdater (Base, SectionHeader.Misc.VirtualSize);
178 } else {
179 DEBUG ((
180 DEBUG_WARN,
181 "%a: Mapping section %d of image at 0x%lx with RW-XN permissions and size 0x%x\n",
182 __func__,
183 Index,
184 Base,
185 SectionHeader.Misc.VirtualSize
186 ));
187 }
188 } else {
189 DEBUG ((
190 DEBUG_INFO,
191 "%a: Mapping section %d of image at 0x%lx with RO-X permissions and size 0x%x\n",
192 __func__,
193 Index,
194 Base,
195 SectionHeader.Misc.VirtualSize
196 ));
197 ReadOnlyUpdater (Base, SectionHeader.Misc.VirtualSize);
198 NoExecUpdater (Base, SectionHeader.Misc.VirtualSize);
199 }
200
201 SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
202 }
203
204 return RETURN_SUCCESS;
205}
206
216VOID
217EFIAPI
220 )
221{
222 UpdatePeCoffPermissions (
223 ImageContext,
224 ArmClearMemoryRegionNoExec,
225 ArmSetMemoryRegionReadOnly
226 );
227}
228
239VOID
240EFIAPI
243 )
244{
245 UpdatePeCoffPermissions (
246 ImageContext,
247 ArmSetMemoryRegionNoExec,
248 ArmClearMemoryRegionReadOnly
249 );
250}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define RETURN_ERROR(StatusCode)
Definition: Base.h:1061
#define ALIGN_VALUE(Value, Alignment)
Definition: Base.h:948
#define RETURN_SUCCESS
Definition: Base.h:1066
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
RETURN_STATUS EFIAPI PeCoffLoaderGetImageInfo(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: BasePeCoff.c:577
#define EFI_IMAGE_SCN_MEM_EXECUTE
0x20000000
Definition: PeImage.h:341
#define EFI_IMAGE_SCN_MEM_WRITE
0x80000000
Definition: PeImage.h:343
#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
Definition: PeImage.h:143
#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: PeImage.h:194
VOID EFIAPI PeCoffLoaderUnloadImageExtraAction(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
VOID EFIAPI PeCoffLoaderRelocateImageExtraAction(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
PE_COFF_LOADER_READ_FILE ImageRead
Definition: PeCoffLib.h:100
PHYSICAL_ADDRESS ImageAddress
Definition: PeCoffLib.h:79