From 74135485840dd2cab6b283917a4c28e27f788886 Mon Sep 17 00:00:00 2001 From: Savva Mitrofanov Date: Wed, 26 Oct 2022 21:19:26 +0600 Subject: [PATCH] Ext4Pkg: Fix global buffer overflow in Ext4ReadDir Directory entry structure can contain name_len bigger than size of "." or "..", that's why CompareMem in such cases leads to global buffer overflow. So there are two problems. The first is that statement doesn't check cases when name_len != 0 but > 2 and the second is that we passing big Length to CompareMem routine. The correct way here is to check that name_len <= 2 and check for null-terminator presence Signed-off-by: Savva Mitrofanov --- Ext4Pkg/Ext4Dxe/Directory.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Ext4Pkg/Ext4Dxe/Directory.c b/Ext4Pkg/Ext4Dxe/Directory.c index 8b8fce568e..ffc0e80430 100644 --- a/Ext4Pkg/Ext4Dxe/Directory.c +++ b/Ext4Pkg/Ext4Dxe/Directory.c @@ -491,11 +491,9 @@ Ext4ReadDir ( // Entry.name_len may be 0 if it's a nameless entry, like an unused entry // or a checksum at the end of the directory block. - // memcmp (and CompareMem) return 0 when the passed length is 0. - - IsDotOrDotDot = Entry.name_len != 0 && - (CompareMem (Entry.name, ".", Entry.name_len) == 0 || - CompareMem (Entry.name, "..", Entry.name_len) == 0); + IsDotOrDotDot = Entry.name_len <= 2 && + ((Entry.name[0] == '.') && + (Entry.name[1] == '.' || Entry.name[1] == '\0')); // When inode = 0, it's unused. ShouldSkip = Entry.inode == 0 || IsDotOrDotDot;