TianoCore EDK2 master
Loading...
Searching...
No Matches
SetPermissions.c
Go to the documentation of this file.
1
10#include <PiMm.h>
11
12#include <PiPei.h>
14#include <Guid/MpInformation.h>
15
17#include <Library/ArmMmuLib.h>
18#include <Library/ArmSvcLib.h>
19#include <Library/DebugLib.h>
20#include <Library/HobLib.h>
21#include <Library/BaseLib.h>
24
26
43EFIAPI
46 IN EFI_PHYSICAL_ADDRESS ImageBase,
47 IN UINT32 SectionHeaderOffset,
48 IN CONST UINT16 NumberOfSections,
49 IN REGION_PERMISSION_UPDATE_FUNC TextUpdater,
50 IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater,
51 IN REGION_PERMISSION_UPDATE_FUNC ReadWriteUpdater
52 )
53{
54 EFI_IMAGE_SECTION_HEADER SectionHeader;
55 RETURN_STATUS Status;
57 UINTN Size;
58 UINTN ReadSize;
59 UINTN Index;
60
61 ASSERT (ImageContext != NULL);
62
63 //
64 // Iterate over the sections
65 //
66 for (Index = 0; Index < NumberOfSections; Index++) {
67 //
68 // Read section header from file
69 //
70 Size = sizeof (EFI_IMAGE_SECTION_HEADER);
71 ReadSize = Size;
72 Status = ImageContext->ImageRead (
73 ImageContext->Handle,
74 SectionHeaderOffset,
75 &Size,
76 &SectionHeader
77 );
78
79 if (RETURN_ERROR (Status) || (Size != ReadSize)) {
80 DEBUG ((
81 DEBUG_ERROR,
82 "%a: ImageContext->ImageRead () failed (Status = %r)\n",
83 __func__,
84 Status
85 ));
86 return Status;
87 }
88
89 DEBUG ((
90 DEBUG_INFO,
91 "%a: Section %d of image at 0x%lx has 0x%x permissions\n",
92 __func__,
93 Index,
94 ImageContext->ImageAddress,
95 SectionHeader.Characteristics
96 ));
97 DEBUG ((
98 DEBUG_INFO,
99 "%a: Section %d of image at 0x%lx has %a name\n",
100 __func__,
101 Index,
102 ImageContext->ImageAddress,
103 SectionHeader.Name
104 ));
105 DEBUG ((
106 DEBUG_INFO,
107 "%a: Section %d of image at 0x%lx has 0x%x address\n",
108 __func__,
109 Index,
110 ImageContext->ImageAddress,
111 ImageContext->ImageAddress + SectionHeader.VirtualAddress
112 ));
113 DEBUG ((
114 DEBUG_INFO,
115 "%a: Section %d of image at 0x%lx has 0x%x data\n",
116 __func__,
117 Index,
118 ImageContext->ImageAddress,
119 SectionHeader.PointerToRawData
120 ));
121
122 //
123 // If the section is marked as XN then remove the X attribute. Furthermore,
124 // if it is a writeable section then mark it appropriately as well.
125 //
126 if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) == 0) {
127 Base = ImageBase + SectionHeader.VirtualAddress;
128
129 TextUpdater (Base, SectionHeader.Misc.VirtualSize);
130
131 if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_MEM_WRITE) != 0) {
132 ReadWriteUpdater (Base, SectionHeader.Misc.VirtualSize);
133 DEBUG ((
134 DEBUG_INFO,
135 "%a: Mapping section %d of image at 0x%lx with RW-XN permissions\n",
136 __func__,
137 Index,
138 ImageContext->ImageAddress
139 ));
140 } else {
141 DEBUG ((
142 DEBUG_INFO,
143 "%a: Mapping section %d of image at 0x%lx with RO-XN permissions\n",
144 __func__,
145 Index,
146 ImageContext->ImageAddress
147 ));
148 }
149 } else {
150 DEBUG ((
151 DEBUG_INFO,
152 "%a: Ignoring section %d of image at 0x%lx with 0x%x permissions\n",
153 __func__,
154 Index,
155 ImageContext->ImageAddress,
156 SectionHeader.Characteristics
157 ));
158 }
159
160 SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
161 }
162
163 return RETURN_SUCCESS;
164}
165
178EFIAPI
180 IN EFI_FIRMWARE_VOLUME_HEADER *BfvAddress,
181 IN OUT VOID **TeData,
182 IN OUT UINTN *TeDataSize
183 )
184{
185 EFI_FFS_FILE_HEADER *FileHeader;
186 EFI_STATUS Status;
187
188 FileHeader = NULL;
189 Status = FfsFindNextFile (
190 EFI_FV_FILETYPE_SECURITY_CORE,
191 BfvAddress,
192 &FileHeader
193 );
194
195 if (EFI_ERROR (Status)) {
196 DEBUG ((
197 DEBUG_ERROR,
198 "Unable to locate Standalone MM FFS file - 0x%x\n",
199 Status
200 ));
201 return Status;
202 }
203
204 Status = FfsFindSectionData (EFI_SECTION_PE32, FileHeader, TeData, TeDataSize);
205 if (EFI_ERROR (Status)) {
206 Status = FfsFindSectionData (EFI_SECTION_TE, FileHeader, TeData, TeDataSize);
207 if (EFI_ERROR (Status)) {
208 DEBUG ((
209 DEBUG_ERROR,
210 "Unable to locate Standalone MM Section data - %r\n",
211 Status
212 ));
213 return Status;
214 }
215 }
216
217 DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", *TeData));
218 return Status;
219}
220
230STATIC
233 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
234 OUT EFI_PHYSICAL_ADDRESS *ImageBase,
235 OUT UINT32 *SectionHeaderOffset,
236 OUT UINT16 *NumberOfSections
237 )
238{
239 RETURN_STATUS Status;
242 UINTN Size;
243 UINTN ReadSize;
244
245 ASSERT (ImageContext != NULL);
246 ASSERT (SectionHeaderOffset != NULL);
247 ASSERT (NumberOfSections != NULL);
248
249 Status = PeCoffLoaderGetImageInfo (ImageContext);
250 if (RETURN_ERROR (Status)) {
251 DEBUG ((
252 DEBUG_ERROR,
253 "%a: PeCoffLoaderGetImageInfo () failed (Status == %r)\n",
254 __func__,
255 Status
256 ));
257 return Status;
258 }
259
260 if (ImageContext->SectionAlignment < EFI_PAGE_SIZE) {
261 //
262 // The sections need to be at least 4 KB aligned, since that is the
263 // granularity at which we can tighten permissions.
264 //
265 if (!ImageContext->IsTeImage) {
266 DEBUG ((
267 DEBUG_WARN,
268 "%a: non-TE Image at 0x%lx has SectionAlignment < 4 KB (%lu)\n",
269 __func__,
270 ImageContext->ImageAddress,
271 ImageContext->SectionAlignment
272 ));
273 return RETURN_UNSUPPORTED;
274 }
275
276 ImageContext->SectionAlignment = EFI_PAGE_SIZE;
277 }
278
279 //
280 // Read the PE/COFF Header. For PE32 (32-bit) this will read in too much
281 // data, but that should not hurt anything. Hdr.Pe32->OptionalHeader.Magic
282 // determines if this is a PE32 or PE32+ image. The magic is in the same
283 // location in both images.
284 //
285 Hdr.Union = &HdrData;
286 Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
287 ReadSize = Size;
288 Status = ImageContext->ImageRead (
289 ImageContext->Handle,
290 ImageContext->PeCoffHeaderOffset,
291 &Size,
292 Hdr.Pe32
293 );
294
295 if (RETURN_ERROR (Status) || (Size != ReadSize)) {
296 DEBUG ((
297 DEBUG_ERROR,
298 "%a: TmpContext->ImageRead () failed (Status = %r)\n",
299 __func__,
300 Status
301 ));
302 return Status;
303 }
304
305 *ImageBase = ImageContext->ImageAddress;
306 if (!ImageContext->IsTeImage) {
307 ASSERT (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE);
308
309 *SectionHeaderOffset = ImageContext->PeCoffHeaderOffset + sizeof (UINT32) +
310 sizeof (EFI_IMAGE_FILE_HEADER);
311 *NumberOfSections = Hdr.Pe32->FileHeader.NumberOfSections;
312
313 switch (Hdr.Pe32->OptionalHeader.Magic) {
315 *SectionHeaderOffset += Hdr.Pe32->FileHeader.SizeOfOptionalHeader;
316 break;
318 *SectionHeaderOffset += Hdr.Pe32Plus->FileHeader.SizeOfOptionalHeader;
319 break;
320 default:
321 ASSERT (FALSE);
322 }
323 } else {
324 *SectionHeaderOffset = (UINTN)(sizeof (EFI_TE_IMAGE_HEADER));
325 *NumberOfSections = Hdr.Te->NumberOfSections;
326 *ImageBase -= (UINT32)Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER);
327 }
328
329 return RETURN_SUCCESS;
330}
331
346EFIAPI
348 IN VOID *TeData,
349 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
350 OUT EFI_PHYSICAL_ADDRESS *ImageBase,
351 IN OUT UINT32 *SectionHeaderOffset,
352 IN OUT UINT16 *NumberOfSections
353 )
354{
355 EFI_STATUS Status;
356
357 // Initialize the Image Context
358 ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
359 ImageContext->Handle = TeData;
360 ImageContext->ImageRead = PeCoffLoaderImageReadFromMemory;
361
362 DEBUG ((DEBUG_INFO, "Found Standalone MM PE data - 0x%x\n", TeData));
363
365 ImageContext,
366 ImageBase,
367 SectionHeaderOffset,
368 NumberOfSections
369 );
370 if (EFI_ERROR (Status)) {
371 DEBUG ((DEBUG_ERROR, "Unable to locate Standalone MM Core PE-COFF Section information - %r\n", Status));
372 return Status;
373 }
374
375 DEBUG ((
376 DEBUG_INFO,
377 "Standalone MM Core PE-COFF SectionHeaderOffset - 0x%x, NumberOfSections - %d\n",
378 *SectionHeaderOffset,
379 *NumberOfSections
380 ));
381
382 return Status;
383}
UINT64 UINTN
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define RETURN_ERROR(StatusCode)
Definition: Base.h:1061
#define RETURN_UNSUPPORTED
Definition: Base.h:1081
#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
RETURN_STATUS EFIAPI PeCoffLoaderImageReadFromMemory(IN VOID *FileHandle, IN UINTN FileOffset, IN OUT UINTN *ReadSize, OUT VOID *Buffer)
Definition: BasePeCoff.c:1992
#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
#define EFI_SECTION_PE32
EFI_STATUS EFIAPI FfsFindSectionData(IN EFI_SECTION_TYPE SectionType, IN EFI_PEI_FILE_HANDLE FileHandle, OUT VOID **SectionData)
Definition: FwVol.c:521
EFI_STATUS EFIAPI FfsFindNextFile(IN EFI_FV_FILETYPE SearchType, IN EFI_PEI_FV_HANDLE VolumeHandle, IN OUT EFI_PEI_FILE_HANDLE *FileHandle)
Definition: FwVol.c:545
EFI_STATUS EFIAPI GetStandaloneMmCorePeCoffSections(IN VOID *TeData, IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, OUT EFI_PHYSICAL_ADDRESS *ImageBase, IN OUT UINT32 *SectionHeaderOffset, IN OUT UINT16 *NumberOfSections)
EFI_STATUS EFIAPI LocateStandaloneMmCorePeCoffData(IN EFI_FIRMWARE_VOLUME_HEADER *BfvAddress, IN OUT VOID **TeData, IN OUT UINTN *TeDataSize)
STATIC EFI_STATUS GetPeCoffSectionInformation(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, OUT EFI_PHYSICAL_ADDRESS *ImageBase, OUT UINT32 *SectionHeaderOffset, OUT UINT16 *NumberOfSections)
EFI_STATUS EFIAPI UpdateMmFoundationPeCoffPermissions(IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, IN EFI_PHYSICAL_ADDRESS ImageBase, IN UINT32 SectionHeaderOffset, IN CONST UINT16 NumberOfSections, IN REGION_PERMISSION_UPDATE_FUNC TextUpdater, IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater, IN REGION_PERMISSION_UPDATE_FUNC ReadWriteUpdater)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINT16 StrippedSize
Number of bytes we removed from the header.
Definition: PeImage.h:785
UINT8 NumberOfSections
From the original file header.
Definition: PeImage.h:783