OpenCore  1.0.4
OpenCore Bootloader
1.0.4
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
TestFatDxe.c
Go to the documentation of this file.
1
6#include <Fat.h>
7
8#include <UserFile.h>
9#include <UserGlobalVar.h>
10#include <UserMemory.h>
12#include <string.h>
13
14extern EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollationInterface;
15
16STATIC EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *mEfiSfsInterface;
17
20CONST UINT8 *mFuzzPointer;
21
22EFI_STATUS
23EFIAPI
25 IN EFI_BLOCK_IO_PROTOCOL *This
26 )
27{
28 return EFI_SUCCESS;
29}
30
31EFI_STATUS
32EFIAPI
34 IN EFI_DISK_IO_PROTOCOL *This,
35 IN UINT32 MediaId,
36 IN UINT64 Offset,
37 IN UINTN BufferSize,
38 OUT VOID *Buffer
39 )
40{
41 if (Buffer == NULL) {
42 return EFI_INVALID_PARAMETER;
43 }
44
45 if ((mFuzzSize - mFuzzOffset) < BufferSize) {
46 return EFI_DEVICE_ERROR;
47 }
48
49 CopyMem (Buffer, mFuzzPointer, BufferSize);
50 mFuzzPointer += BufferSize;
51 mFuzzOffset += BufferSize;
52
53 return EFI_SUCCESS;
54}
55
56EFI_STATUS
57EFIAPI
59 IN OUT EFI_HANDLE *Handle,
60 ...
61 )
62{
63 VA_LIST Args;
64 EFI_STATUS Status;
65 EFI_GUID *Protocol;
66 VOID *Interface;
67
68 if (Handle == NULL) {
69 return EFI_INVALID_PARAMETER;
70 }
71
72 VA_START (Args, Handle);
73 for (Status = EFI_SUCCESS; !EFI_ERROR (Status);) {
74 //
75 // If protocol is NULL, then it's the end of the list
76 //
77 Protocol = VA_ARG (Args, EFI_GUID *);
78 if (Protocol == NULL) {
79 break;
80 }
81
82 Interface = VA_ARG (Args, VOID *);
83
84 //
85 // If this is Sfs protocol then save interface into global state
86 //
88 mEfiSfsInterface = Interface;
89 }
90 }
91
92 VA_END (Args);
93
94 return Status;
95}
96
97VOID
99 IN CHAR16 *FileName,
100 IN FAT_VOLUME *Volume,
101 IN EFI_FILE_PROTOCOL *RootDirInstance
102 )
103{
104 FreePool (FileName);
105
106 //
107 // Closes root directory
108 //
109 if (RootDirInstance != NULL) {
110 FatClose (RootDirInstance);
111 }
112
113 //
114 // Abandon volume structure
115 //
116 if (Volume != NULL) {
117 if (Volume->DiskIo != NULL) {
118 FreePool (Volume->DiskIo);
119 }
120
121 if (Volume->BlockIo != NULL) {
122 if (Volume->BlockIo->Media != NULL) {
123 FreePool (Volume->BlockIo->Media);
124 }
125
126 FreePool (Volume->BlockIo);
127 }
128
129 if (Volume->Root != NULL) {
130 FatSetVolumeError (
131 Volume->Root,
132 EFI_NO_MEDIA
133 );
134 }
135
136 Volume->Valid = FALSE;
137
138 FatCleanupVolume (Volume, NULL, EFI_SUCCESS, NULL);
139 }
140}
141
142STATIC
143INT32
145 CONST UINT8 *FuzzData,
146 UINTN FuzzSize
147 )
148{
149 EFI_STATUS Status;
150 EFI_FILE_PROTOCOL *VolumeRootDir;
151 UINTN BufferSize;
152 VOID *Buffer;
153 VOID *TmpBuffer;
154 EFI_FILE_PROTOCOL *NewHandle;
155 CHAR16 *FileName;
156 VOID *Info;
157 UINTN Len;
158 UINT64 Position;
159 EFI_DISK_IO_PROTOCOL *DiskIo;
160 EFI_BLOCK_IO_PROTOCOL *BlockIo;
161 FAT_VOLUME *Volume;
162 FAT_IFILE *FileInstance;
163 UINT64 FileSize;
164
165 EFI_HANDLE DeviceHandle;
166
167 BufferSize = 100;
168
169 mFuzzOffset = 0;
170 mFuzzSize = FuzzSize;
171 mFuzzPointer = FuzzData;
172 mEfiSfsInterface = NULL;
173 Volume = NULL;
174 VolumeRootDir = NULL;
175 Position = 0;
176
177 DeviceHandle = (EFI_HANDLE)0xDEADDEADULL;
178
179 //
180 // Construct File Name
181 //
182 FileName = AllocateZeroPool (BufferSize);
183 if (FileName == NULL) {
184 return 0;
185 }
186
187 ASAN_CHECK_MEMORY_REGION (FileName, BufferSize);
188
189 if ((mFuzzSize - mFuzzOffset) < BufferSize) {
190 FreeAll (FileName, Volume, VolumeRootDir);
191 return 0;
192 }
193
194 CopyMem (FileName, mFuzzPointer, BufferSize - 2);
195 mFuzzPointer += BufferSize - 2;
196 mFuzzOffset += BufferSize - 2;
197
198 //
199 // Construct BlockIo and DiskIo interfaces
200 //
201 DiskIo = AllocateZeroPool (sizeof (EFI_DISK_IO_PROTOCOL));
202 if (DiskIo == NULL) {
203 FreeAll (FileName, Volume, VolumeRootDir);
204 return 0;
205 }
206
207 ASAN_CHECK_MEMORY_REGION (DiskIo, sizeof (EFI_DISK_IO_PROTOCOL));
208
209 DiskIo->ReadDisk = FuzzReadDisk;
210
211 BlockIo = AllocateZeroPool (sizeof (EFI_BLOCK_IO_PROTOCOL));
212 if (BlockIo == NULL) {
213 FreePool (DiskIo);
214 FreeAll (FileName, Volume, VolumeRootDir);
215 return 0;
216 }
217
218 ASAN_CHECK_MEMORY_REGION (BlockIo, sizeof (EFI_BLOCK_IO_PROTOCOL));
219
220 BlockIo->Media = AllocateZeroPool (sizeof (EFI_BLOCK_IO_MEDIA));
221 if (BlockIo->Media == NULL) {
222 FreePool (DiskIo);
223 FreePool (BlockIo);
224 FreeAll (FileName, Volume, VolumeRootDir);
225 return 0;
226 }
227
228 ASAN_CHECK_MEMORY_REGION (BlockIo->Media, sizeof (EFI_BLOCK_IO_MEDIA));
229
230 BlockIo->FlushBlocks = FuzzBlockIoFlushBlocks;
231
232 //
233 // Allocate volume
234 //
235 Status = FatAllocateVolume (DeviceHandle, DiskIo, NULL, BlockIo);
236
237 if (EFI_ERROR (Status)) {
238 FreePool (BlockIo->Media);
239 FreePool (BlockIo);
240 FreePool (DiskIo);
241 FreeAll (FileName, Volume, VolumeRootDir);
242 return 0;
243 }
244
245 //
246 // Open volume root dir
247 //
248 Status = FatOpenVolume (mEfiSfsInterface, &VolumeRootDir);
249
250 if (EFI_ERROR (Status)) {
251 FreeAll (FileName, Volume, VolumeRootDir);
252 return 0;
253 }
254
255 Volume = VOLUME_FROM_VOL_INTERFACE (mEfiSfsInterface);
256
257 //
258 // Open File
259 //
260 Status = FatOpen (VolumeRootDir, &NewHandle, FileName, EFI_FILE_MODE_READ, 0);
261 if (Status == EFI_SUCCESS) {
262 //
263 // Try to read 100 bytes
264 //
265 Buffer = AllocateZeroPool (100);
266 BufferSize = 100;
267 if (Buffer == NULL) {
268 FatClose (NewHandle);
269 FreeAll (FileName, Volume, VolumeRootDir);
270 return 0;
271 }
272
273 Status = FatRead (NewHandle, &BufferSize, Buffer);
274 if (Status == EFI_BUFFER_TOO_SMALL) {
275 TmpBuffer = ReallocatePool (100, BufferSize, Buffer);
276 if (TmpBuffer == NULL) {
277 FreePool (Buffer);
278 FatClose (NewHandle);
279 FreeAll (FileName, Volume, VolumeRootDir);
280 return 0;
281 }
282
283 Buffer = TmpBuffer;
284
285 ASAN_CHECK_MEMORY_REGION (Buffer, BufferSize);
286
287 FatRead (NewHandle, &BufferSize, Buffer);
288 }
289
290 FatWrite (NewHandle, &BufferSize, Buffer);
291
292 FatFlush (NewHandle);
293
294 FreePool (Buffer);
295
296 //
297 // Set/Get file info
298 //
299 Len = 0;
300 Info = NULL;
301 Status = FatGetInfo (NewHandle, &gEfiFileInfoGuid, &Len, Info);
302 if (Status == EFI_BUFFER_TOO_SMALL) {
303 Info = AllocateZeroPool (Len);
304 if (Info == NULL) {
305 FatClose (NewHandle);
306 FreeAll (FileName, Volume, VolumeRootDir);
307 return 0;
308 }
309
310 Status = FatGetInfo (NewHandle, &gEfiFileInfoGuid, &Len, Info);
311 if (!EFI_ERROR (Status)) {
312 //
313 // Try to set this info back
314 //
315 FatSetInfo (NewHandle, &gEfiFileInfoGuid, Len, Info);
316 FreePool (Info);
317 }
318 }
319
320 Len = 0;
321 Info = NULL;
322 Status = FatGetInfo (NewHandle, &gEfiFileSystemInfoGuid, &Len, Info);
323 if (Status == EFI_BUFFER_TOO_SMALL) {
324 Info = AllocateZeroPool (Len);
325 if (Info == NULL) {
326 FatClose (NewHandle);
327 FreeAll (FileName, Volume, VolumeRootDir);
328 return 0;
329 }
330
331 Status = FatGetInfo (NewHandle, &gEfiFileSystemInfoGuid, &Len, Info);
332 if (!EFI_ERROR (Status)) {
333 //
334 // Try to set this info back
335 //
336 FatSetInfo (NewHandle, &gEfiFileSystemInfoGuid, Len, Info);
337 FreePool (Info);
338 }
339 }
340
341 Len = 0;
342 Info = NULL;
343 Status = FatGetInfo (NewHandle, &gEfiFileSystemVolumeLabelInfoIdGuid, &Len, Info);
344 if (Status == EFI_BUFFER_TOO_SMALL) {
345 Info = AllocateZeroPool (Len);
346 if (Info == NULL) {
347 FatClose (NewHandle);
348 FreeAll (FileName, Volume, VolumeRootDir);
349 return 0;
350 }
351
352 Status = FatGetInfo (NewHandle, &gEfiFileSystemVolumeLabelInfoIdGuid, &Len, Info);
353 if (!EFI_ERROR (Status)) {
354 //
355 // Try to set this info back
356 //
357 FatSetInfo (NewHandle, &gEfiFileSystemVolumeLabelInfoIdGuid, Len, Info);
358 FreePool (Info);
359 }
360 }
361
362 //
363 // Test position functions
364 //
365 FatGetPosition (NewHandle, &Position);
366 FatSetPosition (NewHandle, Position);
367
368 //
369 // Trying to reach the end of file and read/write it
370 //
371 Position = (UINT64)-1;
372 Status = FatSetPosition (NewHandle, Position);
373 if (!EFI_ERROR (Status)) {
374 Buffer = AllocateZeroPool (100);
375 BufferSize = 100;
376
377 if (Buffer == NULL) {
378 FatClose (NewHandle);
379 FreeAll (FileName, Volume, VolumeRootDir);
380 return 0;
381 }
382
383 Status = FatRead (NewHandle, &BufferSize, Buffer);
384 if (Status == EFI_BUFFER_TOO_SMALL) {
385 TmpBuffer = ReallocatePool (100, BufferSize, Buffer);
386 if (TmpBuffer == NULL) {
387 FreePool (Buffer);
388 FatClose (NewHandle);
389 FreeAll (FileName, Volume, VolumeRootDir);
390 return 0;
391 }
392
393 Buffer = TmpBuffer;
394
395 ASAN_CHECK_MEMORY_REGION (Buffer, BufferSize);
396
397 FatRead (NewHandle, &BufferSize, Buffer);
398 }
399
400 FatWrite (NewHandle, &BufferSize, Buffer);
401
402 FatFlush (NewHandle);
403
404 FreePool (Buffer);
405 }
406
407 //
408 // Trying to reach out of bound of FileSize
409 //
410 FileInstance = IFILE_FROM_FHAND (NewHandle);
411 FileSize = FileInstance->OFile->FileSize;
412 if (FileSize < (UINT64)-1 - 1) {
413 Position = FileSize + 1;
414 Status = FatSetPosition (NewHandle, Position);
415 if (!EFI_ERROR (Status)) {
416 Buffer = AllocateZeroPool (100);
417 BufferSize = 100;
418 if (Buffer == NULL) {
419 FatClose (NewHandle);
420 FreeAll (FileName, Volume, VolumeRootDir);
421 return 0;
422 }
423
424 Status = FatRead (NewHandle, &BufferSize, Buffer);
425
426 ASSERT (Status == EFI_DEVICE_ERROR);
427 FreePool (Buffer);
428 }
429 }
430
431 FatDelete (NewHandle);
432 }
433
434 FreeAll (FileName, Volume, VolumeRootDir);
435
436 return 0;
437}
438
439INT32
441 CONST UINT8 *FuzzData,
442 UINTN FuzzSize
443 )
444{
445 VOID *NewData;
446
447 #ifdef MEMORY_MUTATIONS
448 UINT32 ConfigSize;
449 #endif
450
451 if (FuzzSize == 0) {
452 return 0;
453 }
454
455 // Set up unicode collation protocol
457
458 //
459 // Override InstallMultipleProtocolInterfaces with custom wrapper
460 //
461 gBS->InstallMultipleProtocolInterfaces = WrapInstallMultipleProtocolInterfaces;
462
463 #ifdef MEMORY_MUTATIONS
464 ConfigSize = 0;
465 ConfigureMemoryAllocations (FuzzData, FuzzSize, &ConfigSize);
466 #endif
467 SetPoolAllocationSizeLimit (BASE_1GB | BASE_2GB);
468
469 NewData = AllocatePool (FuzzSize);
470 if (NewData != NULL) {
471 CopyMem (NewData, FuzzData, FuzzSize);
472 TestFatDxe (NewData, FuzzSize);
473 FreePool (NewData);
474 }
475
476 DEBUG ((
477 DEBUG_POOL | DEBUG_PAGE,
478 "UMEM: Allocated %u pools %u pages\n",
479 (UINT32)mPoolAllocations,
480 (UINT32)mPageAllocations
481 ));
482
483 return 0;
484}
485
486int
488 int argc,
489 char **argv
490 )
491{
492 uint32_t f;
493 uint8_t *b;
494
495 if ((b = UserReadFile ((argc > 1) ? argv[1] : "in.bin", &f)) == NULL) {
496 DEBUG ((DEBUG_ERROR, "Read fail\n"));
497 return -1;
498 }
499
501 FreePool (b);
502 return 0;
503}
EFI_BOOT_SERVICES * gBS
OC_TYPING_BUFFER_ENTRY Buffer[OC_TYPING_BUFFER_SIZE]
Definition OcTypingLib.h:42
APPLE_EVENT_HANDLE Handle
Definition OcTypingLib.h:45
STATIC EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * mEfiSfsInterface
Definition TestFatDxe.c:16
EFI_STATUS EFIAPI FuzzReadDisk(IN EFI_DISK_IO_PROTOCOL *This, IN UINT32 MediaId, IN UINT64 Offset, IN UINTN BufferSize, OUT VOID *Buffer)
Definition TestFatDxe.c:33
STATIC INT32 TestFatDxe(CONST UINT8 *FuzzData, UINTN FuzzSize)
Definition TestFatDxe.c:144
EFI_STATUS EFIAPI WrapInstallMultipleProtocolInterfaces(IN OUT EFI_HANDLE *Handle,...)
Definition TestFatDxe.c:58
EFI_UNICODE_COLLATION_PROTOCOL * mUnicodeCollationInterface
CONST UINT8 * mFuzzPointer
Definition TestFatDxe.c:20
VOID FreeAll(IN CHAR16 *FileName, IN FAT_VOLUME *Volume, IN EFI_FILE_PROTOCOL *RootDirInstance)
Definition TestFatDxe.c:98
INT32 LLVMFuzzerTestOneInput(CONST UINT8 *FuzzData, UINTN FuzzSize)
Definition TestFatDxe.c:440
UINTN mFuzzSize
Definition TestFatDxe.c:19
EFI_STATUS EFIAPI FuzzBlockIoFlushBlocks(IN EFI_BLOCK_IO_PROTOCOL *This)
Definition TestFatDxe.c:24
UINTN mFuzzOffset
Definition TestFatDxe.c:18
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
UINT8 * UserReadFile(IN CONST CHAR8 *FileName, OUT UINT32 *Size)
Definition UserFile.c:62
EFI_GUID gEfiFileInfoGuid
EFI_GUID gEfiFileSystemInfoGuid
EFI_GUID gEfiSimpleFileSystemProtocolGuid
#define ASAN_CHECK_MEMORY_REGION(addr, size)
EFI_GUID gEfiFileSystemVolumeLabelInfoIdGuid
VOID SetPoolAllocationSizeLimit(UINTN AllocationSize)
UINTN mPageAllocations
UINTN mPoolAllocations
VOID ConfigureMemoryAllocations(IN CONST UINT8 *Data, IN UINTN Size, IN OUT UINT32 *ConfigSize)
VOID UserUnicodeCollationInstallProtocol(OUT EFI_UNICODE_COLLATION_PROTOCOL **Interface)
#define ASSERT(x)
Definition coder.h:55
#define Len
Definition deflate.h:82
UINT8 uint8_t
UINT32 uint32_t
int ENTRY_POINT(void)