From nobody Sat May 4 16:21:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+79662+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+79662+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1629557301; cv=none; d=zohomail.com; s=zohoarc; b=XMCwGBrL1Xv9W3fdJreSgvoa2NbSAZMw7oDH1CTr90094OgsbeKWy9U9J5guvX4klSGG03lmpxDYFdEIANoXww58YhIHy8G2bh7FLneKab5n7718Z1Qm4gSKa/JkT3ns3Coa2zEwL98D9kNatH3qkcUYT6WSfSQENOQoD7zBDac= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1629557301; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=UL+4Uj48RzL/uTF8UP5+r9mtk5YTDqWfS/jG3wOEslg=; b=UR/nsfNjSn0DUf9C31PSRG0efM8/xn1/hG1lNPBs9QRKXsFFjfrAGf5x6yHmOe4/D2hOeDRxIcT/i0FUf7dqn+um33AigSpGNlmRcnz4p++aQvxVZo1gS/A5T0brrCdzIhPCvy3rHeZVeu3XmO1fuAlJv18rW9tC0c0YfdTlNeU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+79662+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1629557301126765.8887113607669; Sat, 21 Aug 2021 07:48:21 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id aF8dYY1788612xfJPuqtG9f3; Sat, 21 Aug 2021 07:48:20 -0700 X-Received: from mail-wr1-f46.google.com (mail-wr1-f46.google.com [209.85.221.46]) by mx.groups.io with SMTP id smtpd.web09.11631.1629557300023258598 for ; Sat, 21 Aug 2021 07:48:20 -0700 X-Received: by mail-wr1-f46.google.com with SMTP id r7so18669112wrs.0 for ; Sat, 21 Aug 2021 07:48:19 -0700 (PDT) X-Gm-Message-State: ipOX51iUzFo31qlAsm8nRsAAx1787277AA= X-Google-Smtp-Source: ABdhPJzlbVmpHwhto2PyltRf9vA2HEclXNpIbdWQQYQvPpLhoiDMPYKs3YZDh5a+3NJTePIp4Zfn8A== X-Received: by 2002:adf:d083:: with SMTP id y3mr4321585wrh.56.1629557298305; Sat, 21 Aug 2021 07:48:18 -0700 (PDT) X-Received: from PC-PEDRO.lan (bl8-253-151.dsl.telepac.pt. [85.241.253.151]) by smtp.gmail.com with ESMTPSA id j17sm9118036wrt.69.2021.08.21.07.48.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Aug 2021 07:48:18 -0700 (PDT) From: "Pedro Falcato" To: devel@edk2.groups.io Cc: Pedro Falcato , Leif Lindholm , Michael D Kinney , Bret Barkelew Subject: [edk2-devel] [edk2-platforms PATCH v2 1/5] Ext4Pkg: Fix incorrect usage of Ext4InitExtentsMap. Date: Sat, 21 Aug 2021 15:47:06 +0100 Message-Id: <20210821144711.39546-2-pedro.falcato@gmail.com> In-Reply-To: <20210821144711.39546-1-pedro.falcato@gmail.com> References: <20210821144711.39546-1-pedro.falcato@gmail.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pedro.falcato@gmail.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1629557300; bh=9V1VLRO7vNRBeXwhWldsR/pXauMuFw6Z6TCufc0bblU=; h=Cc:Date:From:Reply-To:Subject:To; b=ISSWTuvM+oCYj4yNuAtMaiWoMaelGpy54dDXB1hhPDaRQACROvvlnGtgXHh8nZ466vP NrM65uhTj3Ot0GBH0WYi/esWOnZ/f9jv/8PNgNNk9ssgwDCJV4++Hq8Fm7ejGV5Y+WaZ9 fNA0CTsdaMOJLLzNkNX/Ys7hCrAPQTJXELM= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1629557303128100006 Content-Type: text/plain; charset="utf-8" Fixes bug triggered by ShellPkg code, in usage of EFI_FILE_PROTOCOL's Open(). Cc: Leif Lindholm Cc: Michael D Kinney Cc: Bret Barkelew Signed-off-by: Pedro Falcato Reviewed-by: Michael D Kinney --- Features/Ext4Pkg/Ext4Dxe/File.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/Features/Ext4Pkg/Ext4Dxe/File.c b/Features/Ext4Pkg/Ext4Dxe/Fil= e.c index 0f5fa6f73fb6..a3eff2b48a07 100644 --- a/Features/Ext4Pkg/Ext4Dxe/File.c +++ b/Features/Ext4Pkg/Ext4Dxe/File.c @@ -207,6 +207,11 @@ Ext4Open ( =20 FileName +=3D Length; =20 + if (StrCmp(PathSegment, L".") =3D=3D 0) { + // Opens of "." are a no-op + continue; + } + DEBUG ((DEBUG_FS, "[ext4] Opening %s\n", PathSegment)); =20 if (!Ext4FileIsDir (Current)) { @@ -512,12 +517,20 @@ Ext4GetFileInfo ( IN EXT4_FILE *File, OUT EFI_FILE_INFO *Info, IN OUT UINTN *BufferSize ) { - UINTN FileNameLen; - UINTN FileNameSize; - UINTN NeededLength; + UINTN FileNameLen; + UINTN FileNameSize; + UINTN NeededLength; + CONST CHAR16 *FileName; =20 - FileNameLen =3D StrLen (File->FileName); - FileNameSize =3D StrSize (File->FileName); + if (File->InodeNum =3D=3D 2) { + // Root inode gets a filename of "", regardless of how it was opened. + FileName =3D L""; + } else { + FileName =3D File->FileName; + } + + FileNameLen =3D StrLen (FileName); + FileNameSize =3D StrSize (FileName); =20 NeededLength =3D SIZE_OF_EFI_FILE_INFO + FileNameSize; =20 @@ -540,7 +553,7 @@ Ext4GetFileInfo ( =20 *BufferSize =3D NeededLength; =20 - return StrCpyS (Info->FileName, FileNameLen + 1, File->FileName); + return StrCpyS (Info->FileName, FileNameLen + 1, FileName); } =20 /** @@ -687,6 +700,7 @@ Ext4DuplicateFile ( { EXT4_PARTITION *Partition; EXT4_FILE *File; + EFI_STATUS Status; =20 Partition =3D Original->Partition; File =3D AllocateZeroPool (sizeof (EXT4_FILE)); @@ -717,7 +731,8 @@ Ext4DuplicateFile ( File->InodeNum =3D Original->InodeNum; File->OpenMode =3D 0; // Will be filled by other code =20 - if (!Ext4InitExtentsMap (File)) { + Status =3D Ext4InitExtentsMap (File); + if (EFI_ERROR (Status)) { FreePool (File->FileName); FreePool (File->Inode); FreePool (File); --=20 2.33.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#79662): https://edk2.groups.io/g/devel/message/79662 Mute This Topic: https://groups.io/mt/85043011/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 4 16:21:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+79663+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+79663+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1629557301; cv=none; d=zohomail.com; s=zohoarc; b=TgsVlb1PQY1zGtMEatd37rrS5sdQsAe+Y5o2ckxr5vT10I3w3RRiHt7YSz628SPO0eHkoDQqHUo9vUZBdI0MilezpjcQ9yI1kO7RSaxWXSlVbKZMav3PJ1tPFyO+qmxbrNg6d9kT1f49WQST7JaDowoP19YUMLwW5RFHAidxSOA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1629557301; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=h+TXAlk4CMVNCaxRiJ9DOXkhc0tZXQmyYo3zl6vuBvM=; b=C5yHIzvyJstItT2sSuirme+37OZGwhjoq5S/EwBM+a1V+MFReV6NpuuVWf+FKMU30xgA2XpPL8DISCJ61I5yoCrMEc8Za4h32spOZIEXAzgTDyWcOApJwU/+ifuou17gqPrxe7GESMLTnEBa30F3zo2RQrTvhYTEupNDVHCiVzE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+79663+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1629557301981691.8593361949777; Sat, 21 Aug 2021 07:48:21 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id fGyzYY1788612xyGmNP8IXiY; Sat, 21 Aug 2021 07:48:21 -0700 X-Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) by mx.groups.io with SMTP id smtpd.web09.11632.1629557300939028022 for ; Sat, 21 Aug 2021 07:48:21 -0700 X-Received: by mail-wm1-f51.google.com with SMTP id u15so7632738wmj.1 for ; Sat, 21 Aug 2021 07:48:20 -0700 (PDT) X-Gm-Message-State: YJn7MmnKqBZTguh3galoQTawx1787277AA= X-Google-Smtp-Source: ABdhPJzVObs6KcQLJr87wXKqkoRGejvnurhDU7eEIRbn+pBYHSce2YKZPjKW2ML44Uttyeu9L5PgUQ== X-Received: by 2002:a05:600c:154f:: with SMTP id f15mr7349712wmg.124.1629557299294; Sat, 21 Aug 2021 07:48:19 -0700 (PDT) X-Received: from PC-PEDRO.lan (bl8-253-151.dsl.telepac.pt. [85.241.253.151]) by smtp.gmail.com with ESMTPSA id j17sm9118036wrt.69.2021.08.21.07.48.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Aug 2021 07:48:19 -0700 (PDT) From: "Pedro Falcato" To: devel@edk2.groups.io Cc: Pedro Falcato , Leif Lindholm , Michael D Kinney , Bret Barkelew Subject: [edk2-devel] [edk2-platforms PATCH v2 2/5] Ext4Pkg: Hide "." and ".." entries from Read() callers. Date: Sat, 21 Aug 2021 15:47:07 +0100 Message-Id: <20210821144711.39546-3-pedro.falcato@gmail.com> In-Reply-To: <20210821144711.39546-1-pedro.falcato@gmail.com> References: <20210821144711.39546-1-pedro.falcato@gmail.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pedro.falcato@gmail.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1629557301; bh=4I9xT8cD7trOxk2NiyDzx8lvaRk4eYBfDpQE5Ujertk=; h=Cc:Date:From:Reply-To:Subject:To; b=v1Xc8zuJubp3tVJSc8RKJZ0pe49s7PNHZFGuXr+4khreprBBc4YFca4TNSLdzSElwkW uA44CCvkxGvj9Oobp0RWQjPpny3jLXgRQ8bZKs+cBWtwnznKVvctjM9n5Y9NBpfXkmkrJ bQwshPhBTYIqWlbwc0qAZuFBoivuHpBWxQk= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1629558204091100001 Content-Type: text/plain; charset="utf-8" This makes it so callers that may expect FAT32 filesystems (most do) have more normal looking ReadDir() results. This commit also presents a better filename for files opened through Open("."). Cc: Leif Lindholm Cc: Michael D Kinney Cc: Bret Barkelew Signed-off-by: Pedro Falcato Reviewed-by: Michael D Kinney --- Features/Ext4Pkg/Ext4Dxe/Directory.c | 45 +++++++++++++++++++++++----- Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h | 4 ++- Features/Ext4Pkg/Ext4Dxe/Inode.c | 2 +- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/Features/Ext4Pkg/Ext4Dxe/Directory.c b/Features/Ext4Pkg/Ext4Dx= e/Directory.c index 081c6bf0f435..c85c4df6d5c5 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Directory.c +++ b/Features/Ext4Pkg/Ext4Dxe/Directory.c @@ -180,6 +180,7 @@ Ext4RetrieveDirent ( @param[in] OpenMode Mode in which the file is supposed to be op= en. @param[out] OutFile Pointer to the newly opened file. @param[in] Entry Directory entry to be used. + @param[in] Directory Pointer to the opened directory. =20 @retval EFI_STATUS Result of the operation **/ @@ -188,12 +189,18 @@ Ext4OpenDirent ( IN EXT4_PARTITION *Partition, IN UINT64 OpenMode, OUT EXT4_FILE **OutFile, - IN EXT4_DIR_ENTRY *Entry + IN EXT4_DIR_ENTRY *Entry, + IN EXT4_FILE *Directory ) { EFI_STATUS Status; - CHAR16 FileName[EXT4_NAME_MAX + 1]; + CHAR16 FileNameBuf[EXT4_NAME_MAX + 1]; EXT4_FILE *File; + CHAR16 *FileName; + UINTN DestMax; + + FileName =3D FileNameBuf; + DestMax =3D ARRAY_SIZE (FileNameBuf); =20 File =3D AllocateZeroPool (sizeof (EXT4_FILE)); =20 @@ -202,12 +209,18 @@ Ext4OpenDirent ( goto Error; } =20 - Status =3D Ext4GetUcs2DirentName (Entry, FileName); + Status =3D Ext4GetUcs2DirentName (Entry, FileNameBuf); =20 if (EFI_ERROR (Status)) { goto Error; } =20 + if (StrCmp (FileNameBuf, L".") =3D=3D 0) { + // We're using the parent directory's name + FileName =3D Directory->FileName; + DestMax =3D StrLen (FileName) + 1; + } + File->FileName =3D AllocateZeroPool (StrSize (FileName)); =20 if (!File->FileName) { @@ -222,7 +235,7 @@ Ext4OpenDirent ( } =20 // This should not fail. - StrCpyS (File->FileName, ARRAY_SIZE (FileName), FileName); + StrCpyS (File->FileName, DestMax, FileName); =20 File->InodeNum =3D Entry->inode; =20 @@ -290,7 +303,7 @@ Ext4OpenFile ( return EFI_NOT_FOUND; } =20 - return Ext4OpenDirent (Partition, OpenMode, OutFile, &Entry); + return Ext4OpenDirent (Partition, OpenMode, OutFile, &Entry, Directory); } =20 /** @@ -429,6 +442,8 @@ Ext4ReadDir ( UINT32 BlockRemainder; EXT4_DIR_ENTRY Entry; EXT4_FILE *TempFile; + BOOLEAN ShouldSkip; + BOOLEAN IsDotOrDotDot; =20 DirIno =3D File->Inode; Status =3D EFI_SUCCESS; @@ -470,13 +485,27 @@ Ext4ReadDir ( goto Out; } =20 - if (Entry.inode =3D=3D 0) { - // When inode =3D 0, it's unused + // We don't care about passing . or .. entries to the caller of ReadDi= r(), + // since they're generally useless entries *and* may break things if t= oo + // many callers assume FAT32. + + // Entry.name_len may be 0 if it's a nameless entry, like an unused en= try + // or a checksum at the end of the directory block. + // memcmp (and CompareMem) return 0 when the passed length is 0. + + IsDotOrDotDot =3D Entry.name_len !=3D 0 && + (CompareMem (Entry.name, ".", Entry.name_len) =3D=3D 0= || + CompareMem (Entry.name, "..", Entry.name_len) =3D=3D = 0); + + // When inode =3D 0, it's unused. + ShouldSkip =3D Entry.inode =3D=3D 0 || IsDotOrDotDot; + + if (ShouldSkip) { Offset +=3D Entry.rec_len; continue; } =20 - Status =3D Ext4OpenDirent (Partition, EFI_FILE_MODE_READ, &TempFile, &= Entry); + Status =3D Ext4OpenDirent (Partition, EFI_FILE_MODE_READ, &TempFile, &= Entry, File); =20 if (EFI_ERROR (Status)) { goto Out; diff --git a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h b/Features/Ext4Pkg/Ext4Dxe/= Ext4Dxe.h index 93f0a8a04add..1aafc60ab57d 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h +++ b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h @@ -353,6 +353,7 @@ Ext4OpenFile ( @param[in] OpenMode Mode in which the file is supposed to be op= en. @param[out] OutFile Pointer to the newly opened file. @param[in] Entry Directory entry to be used. + @param[in] Directory Pointer to the opened directory. =20 @retval EFI_STATUS Result of the operation **/ @@ -361,7 +362,8 @@ Ext4OpenDirent ( IN EXT4_PARTITION *Partition, IN UINT64 OpenMode, OUT EXT4_FILE **OutFile, - IN EXT4_DIR_ENTRY *Entry + IN EXT4_DIR_ENTRY *Entry, + IN EXT4_FILE *Directory ); =20 /** diff --git a/Features/Ext4Pkg/Ext4Dxe/Inode.c b/Features/Ext4Pkg/Ext4Dxe/In= ode.c index 1bbff9e69f4c..982b19c763d0 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Inode.c +++ b/Features/Ext4Pkg/Ext4Dxe/Inode.c @@ -89,7 +89,7 @@ Ext4Read ( IN OUT UINTN *Length ) { - DEBUG ((DEBUG_FS, "[ext4] Ext4Read(Offset %lu, Length %lu)\n", Offset, *= Length)); + DEBUG ((DEBUG_FS, "[ext4] Ext4Read(%s, Offset %lu, Length %lu)\n", File-= >FileName, Offset, *Length)); EXT4_INODE *Inode; UINT64 InodeSize; UINT64 CurrentSeek; --=20 2.33.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#79663): https://edk2.groups.io/g/devel/message/79663 Mute This Topic: https://groups.io/mt/85043012/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 4 16:21:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+79664+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+79664+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1629557303; cv=none; d=zohomail.com; s=zohoarc; b=i+Rv1lXCkVzSwcEPhBEsRcvi094JF23lUMxqN58Q1wBDA8aC6EDKkY5EGuQcLDKp/GeY1eg1FIaASSSaJ+4ayexHb6D/BlPu9OtUcObofhyRGRHSinnrlXmBajEAwvC544W4n2vZ2xlqXfXzG650Pod+UX6EmdaZDIVYFbrm3AA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1629557303; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=GHZYuzdh4srpSEwJxZW2/WFh5jYkVK47aW4yRe1kBK8=; b=AqStf3w+qIpYMillUAJRHknHCzcRpKUuCTTnrzjef7WvQBZSkN7a3CcvWMK4VNRXYI0C253E1Zn8L+WBzGmyjY23Swp+BYWpNr0K2KvH7B8ZaDeorKp/5PgwcNYEJM/yZAh38XgJQVrFUJUUVdM7QibXWX9rW0JXk5cC90F2NIQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+79664+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1629557303062493.7551557084623; Sat, 21 Aug 2021 07:48:23 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id 3mD6YY1788612xR0rFUb62d6; Sat, 21 Aug 2021 07:48:22 -0700 X-Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) by mx.groups.io with SMTP id smtpd.web10.11603.1629557301845862376 for ; Sat, 21 Aug 2021 07:48:22 -0700 X-Received: by mail-wr1-f49.google.com with SMTP id e5so2017373wrp.8 for ; Sat, 21 Aug 2021 07:48:21 -0700 (PDT) X-Gm-Message-State: V8wkO0EPPZ0GWXck97rDwBRkx1787277AA= X-Google-Smtp-Source: ABdhPJwAVbZKKZ/SBy3YSLaFI/LUK1Af0Bt8Naoz+LxwiRt6GgFsix/q/4iW91UR9VpdZU7ciMX3OQ== X-Received: by 2002:a05:6000:1a86:: with SMTP id f6mr4291989wry.345.1629557300224; Sat, 21 Aug 2021 07:48:20 -0700 (PDT) X-Received: from PC-PEDRO.lan (bl8-253-151.dsl.telepac.pt. [85.241.253.151]) by smtp.gmail.com with ESMTPSA id j17sm9118036wrt.69.2021.08.21.07.48.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Aug 2021 07:48:19 -0700 (PDT) From: "Pedro Falcato" To: devel@edk2.groups.io Cc: Pedro Falcato , Leif Lindholm , Michael D Kinney , Bret Barkelew Subject: [edk2-devel] [edk2-platforms PATCH v2 3/5] Ext4Pkg: Add a directory entry tree. Date: Sat, 21 Aug 2021 15:47:08 +0100 Message-Id: <20210821144711.39546-4-pedro.falcato@gmail.com> In-Reply-To: <20210821144711.39546-1-pedro.falcato@gmail.com> References: <20210821144711.39546-1-pedro.falcato@gmail.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pedro.falcato@gmail.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1629557302; bh=CFOJ5C3n7aiTPweBw9N32L7+XrmpZDvUYnHM6/6u7bU=; h=Cc:Date:From:Reply-To:Subject:To; b=Yj6L2aSNZj78UaTSHhZH8X+H/BwZ1n/H/SzOA+8C3765uPjwOw11QpkdOegrxoOAQoj SAQENnQsM8O8zPq7E9DutwBo1tAWvBTNnY8W5MTgvs28GOrXEiuzPRobyCbsS40nyf8fc sAeBJgJqsF7tk0OSwdyTDouKA/qK7fSZAMc= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1629557305218100013 Content-Type: text/plain; charset="utf-8" This helps us track directories and directory entries, which helps us getting a general idea of how the filesystem looks. In the future, it might serve as a directory cache. Right now, it only lets us know which name "." and ".." may refer to, which fixes a EFI_FILE_PROTOCOL::GetInfo() bug that got triggered by ShellPkg, in some MdePkg code. Cc: Leif Lindholm Cc: Michael D Kinney Cc: Bret Barkelew Signed-off-by: Pedro Falcato Reviewed-by: Michael D Kinney --- Features/Ext4Pkg/Ext4Dxe/Directory.c | 238 +++++++++++++++++++++----- Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h | 3 + Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h | 67 +++++++- Features/Ext4Pkg/Ext4Dxe/File.c | 24 +-- Features/Ext4Pkg/Ext4Dxe/Inode.c | 3 +- Features/Ext4Pkg/Ext4Dxe/Partition.c | 7 + Features/Ext4Pkg/Ext4Dxe/Superblock.c | 23 ++- 7 files changed, 301 insertions(+), 64 deletions(-) diff --git a/Features/Ext4Pkg/Ext4Dxe/Directory.c b/Features/Ext4Pkg/Ext4Dx= e/Directory.c index c85c4df6d5c5..7d1b2dcfe524 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Directory.c +++ b/Features/Ext4Pkg/Ext4Dxe/Directory.c @@ -194,13 +194,8 @@ Ext4OpenDirent ( ) { EFI_STATUS Status; - CHAR16 FileNameBuf[EXT4_NAME_MAX + 1]; + CHAR16 FileName[EXT4_NAME_MAX + 1]; EXT4_FILE *File; - CHAR16 *FileName; - UINTN DestMax; - - FileName =3D FileNameBuf; - DestMax =3D ARRAY_SIZE (FileNameBuf); =20 File =3D AllocateZeroPool (sizeof (EXT4_FILE)); =20 @@ -209,23 +204,32 @@ Ext4OpenDirent ( goto Error; } =20 - Status =3D Ext4GetUcs2DirentName (Entry, FileNameBuf); + Status =3D Ext4GetUcs2DirentName (Entry, FileName); =20 if (EFI_ERROR (Status)) { goto Error; } =20 - if (StrCmp (FileNameBuf, L".") =3D=3D 0) { - // We're using the parent directory's name - FileName =3D Directory->FileName; - DestMax =3D StrLen (FileName) + 1; - } + if (StrCmp (FileName, L".") =3D=3D 0) { + // We're using the parent directory's dentry + File->Dentry =3D Directory->Dentry; =20 - File->FileName =3D AllocateZeroPool (StrSize (FileName)); + ASSERT (File->Dentry !=3D NULL); =20 - if (!File->FileName) { - Status =3D EFI_OUT_OF_RESOURCES; - goto Error; + Ext4RefDentry (File->Dentry); + } else if (StrCmp (FileName, L"..") =3D=3D 0) { + // Using the parent's parent's dentry + File->Dentry =3D Directory->Dentry->Parent; + + ASSERT (File->Dentry !=3D NULL); + + Ext4RefDentry (File->Dentry); + } else { + File->Dentry =3D Ext4CreateDentry (FileName, Directory->Dentry); + + if (!File->Dentry) { + goto Error; + } } =20 Status =3D Ext4InitExtentsMap (File); @@ -234,9 +238,6 @@ Ext4OpenDirent ( goto Error; } =20 - // This should not fail. - StrCpyS (File->FileName, DestMax, FileName); - File->InodeNum =3D Entry->inode; =20 Ext4SetupFile (File, Partition); @@ -255,8 +256,8 @@ Ext4OpenDirent ( =20 Error: if (File !=3D NULL) { - if (File->FileName !=3D NULL) { - FreePool (File->FileName); + if (File->Dentry !=3D NULL) { + Ext4UnrefDentry (File->Dentry); } =20 if (File->ExtentsMap !=3D NULL) { @@ -333,52 +334,47 @@ Ext4OpenVolume ( OUT EFI_FILE_PROTOCOL **Root ) { - EXT4_INODE *RootInode; - EFI_STATUS Status; - EXT4_FILE *RootDir; + EXT4_INODE *RootInode; + EFI_STATUS Status; + EXT4_FILE *RootDir; + EXT4_PARTITION *Partition; =20 - // 2 is always the root inode number in ext4 - Status =3D Ext4ReadInode ((EXT4_PARTITION *)This, 2, &RootInode); + Partition =3D (EXT4_PARTITION *)This; + + Status =3D Ext4ReadInode (Partition, EXT4_ROOT_INODE_NR, &RootInode); =20 if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "[ext4] Could not open root inode - status %x\n",= Status)); + DEBUG ((DEBUG_ERROR, "[ext4] Could not open root inode - error %r\n", = Status)); return Status; } =20 RootDir =3D AllocateZeroPool (sizeof (EXT4_FILE)); =20 - if (!RootDir) { + if (RootDir =3D=3D NULL) { FreePool (RootInode); return EFI_OUT_OF_RESOURCES; } =20 - // The filename will be "\"(null terminated of course) - RootDir->FileName =3D AllocateZeroPool (2 * sizeof (CHAR16)); - - if (!RootDir->FileName) { - FreePool (RootDir); - FreePool (RootInode); - return EFI_OUT_OF_RESOURCES; - } - - RootDir->FileName[0] =3D L'\\'; - RootDir->Inode =3D RootInode; - RootDir->InodeNum =3D 2; + RootDir->InodeNum =3D EXT4_ROOT_INODE_NR; =20 Status =3D Ext4InitExtentsMap (RootDir); =20 if (EFI_ERROR (Status)) { - FreePool (RootDir->FileName); FreePool (RootInode); FreePool (RootDir); return EFI_OUT_OF_RESOURCES; } =20 - Ext4SetupFile (RootDir, (EXT4_PARTITION *)This); + Ext4SetupFile (RootDir, Partition); *Root =3D &RootDir->Protocol; =20 - InsertTailList (&((EXT4_PARTITION *)This)->OpenFiles, &RootDir->OpenFile= sListNode); + InsertTailList (&Partition->OpenFiles, &RootDir->OpenFilesListNode); + + ASSERT (Partition->RootDentry !=3D NULL); + RootDir->Dentry =3D Partition->RootDentry; + + Ext4RefDentry (RootDir->Dentry); =20 return EFI_SUCCESS; } @@ -525,3 +521,159 @@ Ext4ReadDir ( Out: return Status; } + +/** + Removes a dentry from the other's list. + + @param[in out] Parent Pointer to the parent EXT4_DENTR= Y. + @param[in out] ToBeRemoved Pointer to the child EXT4_DENTRY. +**/ +STATIC +VOID +Ext4RemoveDentry ( + IN OUT EXT4_DENTRY *Parent, + IN OUT EXT4_DENTRY *ToBeRemoved + ) +{ + EXT4_DENTRY *D; + LIST_ENTRY *Entry; + LIST_ENTRY *NextEntry; + + BASE_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Parent->Children) { + D =3D EXT4_DENTRY_FROM_DENTRY_LIST (Entry); + + if (D =3D=3D ToBeRemoved) { + RemoveEntryList (Entry); + return; + } + } + + DEBUG ((DEBUG_ERROR, "[ext4] Ext4RemoveDentry did not find the asked-for= dentry\n")); +} + +/** + Adds a dentry to the other's list. + + The dentry that is added to the other one's list gets ->Parent set to P= arent, + and the parent gets its reference count incremented. + + @param[in out] Parent Pointer to the parent EXT4_DENTR= Y. + @param[in out] ToBeAdded Pointer to the child EXT4_DENTRY. +**/ +STATIC +VOID +Ext4AddDentry ( + IN OUT EXT4_DENTRY *Parent, + IN OUT EXT4_DENTRY *ToBeAdded + ) +{ + ToBeAdded->Parent =3D Parent; + InsertTailList (&Parent->Children, &ToBeAdded->ListNode); + Ext4RefDentry (Parent); +} + +/** + Creates a new dentry object. + + @param[in] Name Name of the dentry. + @param[in out opt] Parent Parent dentry, if it's not NULL. + + @return The new allocated and initialised dentry. + The ref count will be set to 1. +**/ +EXT4_DENTRY * +Ext4CreateDentry ( + IN CONST CHAR16 *Name, + IN OUT EXT4_DENTRY *Parent OPTIONAL + ) +{ + EXT4_DENTRY *Dentry; + EFI_STATUS Status; + + Dentry =3D AllocateZeroPool (sizeof (EXT4_DENTRY)); + + if (Dentry =3D=3D NULL) { + return NULL; + } + + Dentry->RefCount =3D 1; + + // This StrCpyS should not fail. + Status =3D StrCpyS (Dentry->Name, ARRAY_SIZE (Dentry->Name), Name); + + ASSERT_EFI_ERROR (Status); + + InitializeListHead (&Dentry->Children); + + if (Parent !=3D NULL) { + Ext4AddDentry (Parent, Dentry); + } + + DEBUG ((DEBUG_FS, "[ext4] Created dentry %s\n", Name)); + + return Dentry; +} + +/** + Increments the ref count of the dentry. + + @param[in out] Dentry Pointer to a valid EXT4_DENTRY. +**/ +VOID +Ext4RefDentry ( + IN OUT EXT4_DENTRY *Dentry + ) +{ + UINTN OldRef; + + OldRef =3D Dentry->RefCount; + + Dentry->RefCount++; + + // I'm not sure if this (Refcount overflow) is a valid concern, + // but it's better to be safe than sorry. + ASSERT (OldRef < Dentry->RefCount); +} + +/** + Deletes the dentry. + + @param[in out] Dentry Pointer to a valid EXT4_DENTRY. +**/ +STATIC +VOID +Ext4DeleteDentry ( + IN OUT EXT4_DENTRY *Dentry + ) +{ + if (Dentry->Parent) { + Ext4RemoveDentry (Dentry->Parent, Dentry); + Ext4UnrefDentry (Dentry->Parent); + } + + DEBUG ((DEBUG_FS, "[ext4] Deleted dentry %s\n", Dentry->Name)); + FreePool (Dentry); +} + +/** + Decrements the ref count of the dentry. + If the ref count is 0, it's destroyed. + + @param[in out] Dentry Pointer to a valid EXT4_DENTRY. + + @retval True if it was destroyed, false if it's alive. +**/ +BOOLEAN +Ext4UnrefDentry ( + IN OUT EXT4_DENTRY *Dentry + ) +{ + Dentry->RefCount--; + + if (Dentry->RefCount =3D=3D 0) { + Ext4DeleteDentry (Dentry); + return TRUE; + } + + return FALSE; +} diff --git a/Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h b/Features/Ext4Pkg/Ext4Dxe= /Ext4Disk.h index b387ebcd36a6..070eb5a9c827 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h +++ b/Features/Ext4Pkg/Ext4Dxe/Ext4Disk.h @@ -451,4 +451,7 @@ typedef struct { typedef UINT64 EXT4_BLOCK_NR; typedef UINT32 EXT4_INO_NR; =20 +// 2 is always the root inode number in ext4 +#define EXT4_ROOT_INODE_NR 2 + #endif diff --git a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h b/Features/Ext4Pkg/Ext4Dxe/= Ext4Dxe.h index 1aafc60ab57d..db938c25244d 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h +++ b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h @@ -55,6 +55,7 @@ Ext4OpenPartition ( ); =20 typedef struct _Ext4File EXT4_FILE; +typedef struct _Ext4_Dentry EXT4_DENTRY; =20 typedef struct _Ext4_PARTITION { EFI_SIMPLE_FILE_SYSTEM_PROTOCOL Interface; @@ -81,8 +82,68 @@ typedef struct _Ext4_PARTITION { UINT32 InitialSeed; =20 LIST_ENTRY OpenFiles; + + EXT4_DENTRY *RootDentry; } EXT4_PARTITION; =20 +/** + This structure represents a directory entry inside our directory entry = tree. + For now, it will be used as a way to track file names inside our openin= g code, + but it may very well be used as a directory cache in the future. + Because it's not being used as a directory cache right now, + an EXT4_DENTRY structure is not necessarily unique name-wise in the lis= t of + children. Therefore, the dentry tree does not accurately reflect the fi= lesystem + structure. + */ +struct _Ext4_Dentry { + UINTN RefCount; + CHAR16 Name[EXT4_NAME_MAX + 1]; + EXT4_INO_NR Inode; + struct _Ext4_Dentry *Parent; + LIST_ENTRY Children; + LIST_ENTRY ListNode; +}; + +#define EXT4_DENTRY_FROM_DENTRY_LIST(Node) BASE_CR (Node, EXT4_DENTRY, Li= stNode) + +/** + Creates a new dentry object. + + @param[in] Name Name of the dentry. + @param[in out opt] Parent Parent dentry, if it's not NULL. + + @return The new allocated and initialised dentry. + The ref count will be set to 1. +**/ +EXT4_DENTRY * +Ext4CreateDentry ( + IN CONST CHAR16 *Name, + IN OUT EXT4_DENTRY *Parent OPTIONAL + ); + +/** + Increments the ref count of the dentry. + + @param[in out] Dentry Pointer to a valid EXT4_DENTRY. +**/ +VOID +Ext4RefDentry ( + IN OUT EXT4_DENTRY *Dentry + ); + +/** + Decrements the ref count of the dentry. + If the ref count is 0, it's destroyed. + + @param[in out] Dentry Pointer to a valid EXT4_DENTRY. + + @retval True if it was destroyed, false if it's alive. +**/ +BOOLEAN +Ext4UnrefDentry ( + IN OUT EXT4_DENTRY *Dentry + ); + /** Opens and parses the superblock. =20 @@ -126,7 +187,7 @@ Ext4OpenSuperblock ( @param[in] Partition Pointer to the opened ext4 partition. @return The media ID associated with the partition. **/ -#define EXT4_MEDIA_ID(Partition) Partition->BlockIo->Media->MediaId +#define EXT4_MEDIA_ID(Partition) Partition->BlockIo->Media->MediaId =20 /** Reads from the partition's disk using the DISK_IO protocol. @@ -299,11 +360,13 @@ struct _Ext4File { UINT64 Position; =20 EXT4_PARTITION *Partition; - CHAR16 *FileName; =20 ORDERED_COLLECTION *ExtentsMap; =20 LIST_ENTRY OpenFilesListNode; + + // Owning reference to this file's directory entry. + EXT4_DENTRY *Dentry; }; =20 #define EXT4_FILE_FROM_OPEN_FILES_NODE(Node) BASE_CR (Node, EXT4_FILE, Op= enFilesListNode) diff --git a/Features/Ext4Pkg/Ext4Dxe/File.c b/Features/Ext4Pkg/Ext4Dxe/Fil= e.c index a3eff2b48a07..021d10b1edfb 100644 --- a/Features/Ext4Pkg/Ext4Dxe/File.c +++ b/Features/Ext4Pkg/Ext4Dxe/File.c @@ -207,7 +207,7 @@ Ext4Open ( =20 FileName +=3D Length; =20 - if (StrCmp(PathSegment, L".") =3D=3D 0) { + if (StrCmp (PathSegment, L".") =3D=3D 0) { // Opens of "." are a no-op continue; } @@ -272,7 +272,7 @@ Ext4Open ( =20 *NewHandle =3D &Current->Protocol; =20 - DEBUG ((DEBUG_FS, "Opened filename %s\n", Current->FileName)); + DEBUG ((DEBUG_FS, "[ext4] Opened filename %s\n", Current->Dentry->Name)); return EFI_SUCCESS; } =20 @@ -312,9 +312,9 @@ Ext4CloseInternal ( =20 DEBUG ((DEBUG_FS, "[ext4] Closed file %p (inode %lu)\n", File, File->Ino= deNum)); RemoveEntryList (&File->OpenFilesListNode); - FreePool (File->FileName); FreePool (File->Inode); Ext4FreeExtentsMap (File); + Ext4UnrefDentry (File->Dentry); FreePool (File); return EFI_SUCCESS; } @@ -522,11 +522,11 @@ Ext4GetFileInfo ( UINTN NeededLength; CONST CHAR16 *FileName; =20 - if (File->InodeNum =3D=3D 2) { + if (File->InodeNum =3D=3D EXT4_ROOT_INODE_NR) { // Root inode gets a filename of "", regardless of how it was opened. FileName =3D L""; } else { - FileName =3D File->FileName; + FileName =3D File->Dentry->Name; } =20 FileNameLen =3D StrLen (FileName); @@ -717,15 +717,6 @@ Ext4DuplicateFile ( =20 CopyMem (File->Inode, Original->Inode, Partition->InodeSize); =20 - File->FileName =3D AllocateZeroPool (StrSize (Original->FileName)); - if (File->FileName =3D=3D NULL) { - FreePool (File->Inode); - FreePool (File); - return NULL; - } - - StrCpyS (File->FileName, StrLen (Original->FileName) + 1, Original->File= Name); - File->Position =3D 0; Ext4SetupFile (File, Partition); File->InodeNum =3D Original->InodeNum; @@ -733,12 +724,15 @@ Ext4DuplicateFile ( =20 Status =3D Ext4InitExtentsMap (File); if (EFI_ERROR (Status)) { - FreePool (File->FileName); FreePool (File->Inode); FreePool (File); return NULL; } =20 + File->Dentry =3D Original->Dentry; + + Ext4RefDentry (File->Dentry); + InsertTailList (&Partition->OpenFiles, &File->OpenFilesListNode); =20 return File; diff --git a/Features/Ext4Pkg/Ext4Dxe/Inode.c b/Features/Ext4Pkg/Ext4Dxe/In= ode.c index 982b19c763d0..63cecec1f7cf 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Inode.c +++ b/Features/Ext4Pkg/Ext4Dxe/Inode.c @@ -89,7 +89,6 @@ Ext4Read ( IN OUT UINTN *Length ) { - DEBUG ((DEBUG_FS, "[ext4] Ext4Read(%s, Offset %lu, Length %lu)\n", File-= >FileName, Offset, *Length)); EXT4_INODE *Inode; UINT64 InodeSize; UINT64 CurrentSeek; @@ -116,6 +115,8 @@ Ext4Read ( RemainingRead =3D *Length; BeenRead =3D 0; =20 + DEBUG ((DEBUG_FS, "[ext4] Ext4Read(%s, Offset %lu, Length %lu)\n", File-= >Dentry->Name, Offset, *Length)); + if (Offset > InodeSize) { return EFI_DEVICE_ERROR; } diff --git a/Features/Ext4Pkg/Ext4Dxe/Partition.c b/Features/Ext4Pkg/Ext4Dx= e/Partition.c index 2258bac76a4f..afa0392024ec 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Partition.c +++ b/Features/Ext4Pkg/Ext4Dxe/Partition.c @@ -108,6 +108,7 @@ Ext4UnmountAndFreePartition ( LIST_ENTRY *Entry; LIST_ENTRY *NextEntry; EXT4_FILE *File; + BOOLEAN DeletedRootDentry; =20 Partition->Unmounting =3D TRUE; Ext4CloseInternal (Partition->Root); @@ -118,6 +119,12 @@ Ext4UnmountAndFreePartition ( Ext4CloseInternal (File); } =20 + DeletedRootDentry =3D Ext4UnrefDentry (Partition->RootDentry); + + if (!DeletedRootDentry) { + DEBUG ((DEBUG_ERROR, "[ext4] Failed to delete root dentry - resource l= eak present.\n")); + } + FreePool (Partition->BlockGroups); FreePool (Partition); =20 diff --git a/Features/Ext4Pkg/Ext4Dxe/Superblock.c b/Features/Ext4Pkg/Ext4D= xe/Superblock.c index 8231831115fa..c321d8c3d86d 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Superblock.c +++ b/Features/Ext4Pkg/Ext4Dxe/Superblock.c @@ -167,8 +167,11 @@ Ext4OpenSuperblock ( // accidentally opening an ext2/3/4 filesystem we don't understand, whic= h would be disasterous. =20 if (Partition->FeaturesIncompat & ~gSupportedIncompatFeat) { - DEBUG ((DEBUG_ERROR, "[ext4] Unsupported features %lx\n", - Partition->FeaturesIncompat & ~gSupportedIncompatFeat)); + DEBUG (( + DEBUG_ERROR, + "[ext4] Unsupported features %lx\n", + Partition->FeaturesIncompat & ~gSupportedIncompatFeat + )); return EFI_UNSUPPORTED; } =20 @@ -247,7 +250,7 @@ Ext4OpenSuperblock ( =20 Partition->BlockGroups =3D Ext4AllocAndReadBlocks (Partition, NrBlocks, = Partition->BlockSize =3D=3D 1024 ? 2 : 1); =20 - if (!Partition->BlockGroups) { + if (Partition->BlockGroups =3D=3D NULL) { return EFI_OUT_OF_RESOURCES; } =20 @@ -255,13 +258,27 @@ Ext4OpenSuperblock ( Desc =3D Ext4GetBlockGroupDesc (Partition, Index); if (!Ext4VerifyBlockGroupDescChecksum (Partition, Desc, Index)) { DEBUG ((DEBUG_ERROR, "[ext4] Block group descriptor %u has an invali= d checksum\n", Index)); + FreePool (Partition->BlockGroups); return EFI_VOLUME_CORRUPTED; } } =20 + // RootDentry will serve as the basis of our directory entry tree. + Partition->RootDentry =3D Ext4CreateDentry (L"\\", NULL); + + if (Partition->RootDentry =3D=3D NULL) { + FreePool (Partition->BlockGroups); + return EFI_OUT_OF_RESOURCES; + } + // Note that the cast below is completely safe, because EXT4_FILE is a s= pecialisation of EFI_FILE_PROTOCOL Status =3D Ext4OpenVolume (&Partition->Interface, (EFI_FILE_PROTOCOL **)= &Partition->Root); =20 + if (EFI_ERROR (Status)) { + Ext4UnrefDentry (Partition->RootDentry); + FreePool (Partition->BlockGroups); + } + return Status; } =20 --=20 2.33.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#79664): https://edk2.groups.io/g/devel/message/79664 Mute This Topic: https://groups.io/mt/85043013/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 4 16:21:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+79665+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+79665+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1629557303; cv=none; d=zohomail.com; s=zohoarc; b=c64PQQWdtOMQ6Kndkst4mq9UesRgC70tSDNAKVEizohQJQLZDhU7jljOBs4WwgrfVkbpugWmHNfKl+9MQJjbbZhfEJwKHaFBuiBnls9f137+hx6BOAaDyVtZXqyX1feP6utQ+mNL4+AABr04xrskP240BX/OSvalzDOVowc0Alk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1629557303; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=M4O88xwlsSefR3HaT43GaAoju4LLYdsRBJRm8isdMU4=; b=IyFb8kkdC26Osx//EbjeeXe4Z2+t6gke6iRrdxUwS5p1706RYFX/NkLbtKZcfW4M7oKsHuHkrPahj0yw2juwFIklGLXHC5FafcNpExYFLo9BaHtaDD9wxaKe/TBDWhJ21LvHAD1Z46lJKTyRS/h/JXF60vPFWLFVvCG6TkzzX38= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+79665+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1629557303832256.2091572951455; Sat, 21 Aug 2021 07:48:23 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id CuRTYY1788612xHXXgQujK2h; Sat, 21 Aug 2021 07:48:23 -0700 X-Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) by mx.groups.io with SMTP id smtpd.web08.11574.1629557302664911308 for ; Sat, 21 Aug 2021 07:48:23 -0700 X-Received: by mail-wr1-f49.google.com with SMTP id r7so18669211wrs.0 for ; Sat, 21 Aug 2021 07:48:22 -0700 (PDT) X-Gm-Message-State: 0aJeK5TRTUpEsymksCkOpvrZx1787277AA= X-Google-Smtp-Source: ABdhPJwRj3SDl8YAUKGiP71URGcbrhsios26tv7J+n6eewBRBtF4Qo1pg4ufgPdduQEdCHJveTfI3w== X-Received: by 2002:adf:f7cf:: with SMTP id a15mr4341863wrq.53.1629557301057; Sat, 21 Aug 2021 07:48:21 -0700 (PDT) X-Received: from PC-PEDRO.lan (bl8-253-151.dsl.telepac.pt. [85.241.253.151]) by smtp.gmail.com with ESMTPSA id j17sm9118036wrt.69.2021.08.21.07.48.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Aug 2021 07:48:20 -0700 (PDT) From: "Pedro Falcato" To: devel@edk2.groups.io Cc: Pedro Falcato , Leif Lindholm , Michael D Kinney , Bret Barkelew Subject: [edk2-devel] [edk2-platforms PATCH v2 4/5] Ext4Pkg: Add handling of EFI_FILE_SYSTEM_VOLUME_LABEL GetInfo(). Date: Sat, 21 Aug 2021 15:47:09 +0100 Message-Id: <20210821144711.39546-5-pedro.falcato@gmail.com> In-Reply-To: <20210821144711.39546-1-pedro.falcato@gmail.com> References: <20210821144711.39546-1-pedro.falcato@gmail.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pedro.falcato@gmail.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1629557303; bh=xb03f0Aliz/u1/UHjaMGn/GCIl1rZ0Mip9iQd9pRFKk=; h=Cc:Date:From:Reply-To:Subject:To; b=ooa5PwEKMJlKl9ner9ztb94z6NJkLEO7Fi0QMLO4PUcM55R5fP1+zjTutNoiBKvNCpi osm0AW64e0rqtMvb+Ti3PVUVvrhS/T/ZIuoI5yFcYfW2syrKYUOmBayPzSV5dbk32/hQq XzIzSvXhLcSoQ3gOEqkIalbWLjRCMKVAZa4= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1629557305251100016 Content-Type: text/plain; charset="utf-8" This commit adds support for EFI_FILE_SYSTEM_VOLUME_LABEL requests in GetInfo(). Cc: Leif Lindholm Cc: Michael D Kinney Cc: Bret Barkelew Signed-off-by: Pedro Falcato Reviewed-by: Michael D Kinney --- Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.c | 1 - Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h | 17 ++++ Features/Ext4Pkg/Ext4Dxe/File.c | 155 ++++++++++++++++++++++------- 3 files changed, 138 insertions(+), 35 deletions(-) diff --git a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.c b/Features/Ext4Pkg/Ext4Dxe/= Ext4Dxe.c index 71360ea894d2..ea2e048d7762 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.c +++ b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.c @@ -6,7 +6,6 @@ **/ =20 #include "Ext4Dxe.h" -#include "Uefi/UefiBaseType.h" =20 GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mExt4DriverNameTab= le[] =3D { { diff --git a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h b/Features/Ext4Pkg/Ext4Dxe/= Ext4Dxe.h index db938c25244d..64eab455db4a 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h +++ b/Features/Ext4Pkg/Ext4Dxe/Ext4Dxe.h @@ -1100,4 +1100,21 @@ Ext4CalculateBlockGroupDescChecksum ( #define EXT4_HAS_GDT_CSUM(Partition) \ EXT4_HAS_RO_COMPAT (Partition, EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) =20 +/** + Retrieves the volume name. + + @param[in] Part Pointer to the opened partition. + @param[out] Info Pointer to a CHAR16*. + @param[out] BufferSize Pointer to a UINTN, where the string len= gth + of the name will be put. + + @return Status of the volume name request. +**/ +EFI_STATUS +Ext4GetVolumeName ( + IN EXT4_PARTITION *Partition, + OUT CHAR16 **OutVolName, + OUT UINTN *VolNameLen + ); + #endif diff --git a/Features/Ext4Pkg/Ext4Dxe/File.c b/Features/Ext4Pkg/Ext4Dxe/Fil= e.c index 021d10b1edfb..4ad7cad8dcf5 100644 --- a/Features/Ext4Pkg/Ext4Dxe/File.c +++ b/Features/Ext4Pkg/Ext4Dxe/File.c @@ -35,7 +35,9 @@ Ext4DuplicateFile ( STATIC EFI_STATUS GetPathSegment ( - IN CONST CHAR16 *Path, OUT CHAR16 *PathSegment, OUT UINTN *Length + IN CONST CHAR16 *Path, + OUT CHAR16 *PathSegment, + OUT UINTN *Length ) { CONST CHAR16 *Start; @@ -514,7 +516,9 @@ Ext4SetPosition ( **/ EFI_STATUS Ext4GetFileInfo ( - IN EXT4_FILE *File, OUT EFI_FILE_INFO *Info, IN OUT UINTN *BufferSize + IN EXT4_FILE *File, + OUT EFI_FILE_INFO *Info, + IN OUT UINTN *BufferSize ) { UINTN FileNameLen; @@ -557,35 +561,33 @@ Ext4GetFileInfo ( } =20 /** - Retrieves information about the filesystem and stores it in the EFI_FIL= E_SYSTEM_INFO format. + Retrieves the volume name. =20 @param[in] Part Pointer to the opened partition. - @param[out] Info Pointer to a EFI_FILE_SYSTEM_INFO. - @param[in out] BufferSize Pointer to the buffer size + @param[out] Info Pointer to a CHAR16*. + @param[out] BufferSize Pointer to a UINTN, where the string len= gth + of the name will be put. =20 - @return Status of the file information request. + @return Status of the volume name request. **/ -STATIC EFI_STATUS -Ext4GetFilesystemInfo ( - IN EXT4_PARTITION *Part, OUT EFI_FILE_SYSTEM_INFO *Info, IN OUT UINTN *B= ufferSize +Ext4GetVolumeName ( + IN EXT4_PARTITION *Partition, + OUT CHAR16 **OutVolName, + OUT UINTN *VolNameLen ) { - // Length of s_volume_name + null terminator - CHAR8 TempVolName[16 + 1]; - CHAR16 *VolumeName; - UINTN VolNameLength; - EFI_STATUS Status; - UINTN NeededLength; - EXT4_BLOCK_NR TotalBlocks; - EXT4_BLOCK_NR FreeBlocks; + CHAR8 TempVolName[16 + 1]; + CHAR16 *VolumeName; + UINTN VolNameLength; + EFI_STATUS Status; =20 VolNameLength =3D 0; VolumeName =3D NULL; =20 // s_volume_name is only valid on dynamic revision; old filesystems don'= t support this - if (Part->SuperBlock.s_rev_level =3D=3D EXT4_DYNAMIC_REV) { - CopyMem (TempVolName, (CONST CHAR8 *)Part->SuperBlock.s_volume_name, 1= 6); + if (Partition->SuperBlock.s_rev_level =3D=3D EXT4_DYNAMIC_REV) { + CopyMem (TempVolName, (CONST CHAR8 *)Partition->SuperBlock.s_volume_na= me, 16); TempVolName[16] =3D '\0'; =20 Status =3D UTF8StrToUCS2 (TempVolName, &VolumeName); @@ -595,23 +597,56 @@ Ext4GetFilesystemInfo ( } =20 VolNameLength =3D StrLen (VolumeName); + } else { + VolumeName =3D AllocateZeroPool (sizeof (CHAR16)); + VolNameLength =3D 0; + } + + *OutVolName =3D VolumeName; + *VolNameLen =3D VolNameLength; + + return EFI_SUCCESS; +} + +/** + Retrieves information about the filesystem and stores it in the EFI_FIL= E_SYSTEM_INFO format. + + @param[in] Part Pointer to the opened partition. + @param[out] Info Pointer to a EFI_FILE_SYSTEM_INFO. + @param[in out] BufferSize Pointer to the buffer size + + @return Status of the file information request. +**/ +STATIC +EFI_STATUS +Ext4GetFilesystemInfo ( + IN EXT4_PARTITION *Part, + OUT EFI_FILE_SYSTEM_INFO *Info, + IN OUT UINTN *BufferSize + ) +{ + // Length of s_volume_name + null terminator + EFI_STATUS Status; + UINTN NeededLength; + EXT4_BLOCK_NR TotalBlocks; + EXT4_BLOCK_NR FreeBlocks; + CHAR16 *VolumeName; + UINTN VolNameLength; + + Status =3D Ext4GetVolumeName (Part, &VolumeName, &VolNameLength); + + if (EFI_ERROR (Status)) { + return Status; } =20 NeededLength =3D SIZE_OF_EFI_FILE_SYSTEM_INFO; =20 - if (VolumeName !=3D NULL) { - NeededLength +=3D StrSize (VolumeName); - } else { - // If we don't have a volume name, we set VolumeLabel to a single null= terminator - NeededLength +=3D sizeof (CHAR16); - } + NeededLength +=3D StrSize (VolumeName); =20 if (*BufferSize < NeededLength) { *BufferSize =3D NeededLength; =20 - if (VolumeName !=3D NULL) { - FreePool (VolumeName); - } + FreePool (VolumeName); =20 return EFI_BUFFER_TOO_SMALL; } @@ -630,16 +665,60 @@ Ext4GetFilesystemInfo ( Info->VolumeSize =3D MultU64x32 (TotalBlocks, Part->BlockSize); Info->FreeSpace =3D MultU64x32 (FreeBlocks, Part->BlockSize); =20 - if (VolumeName !=3D NULL) { - StrCpyS (Info->VolumeLabel, VolNameLength + 1, VolumeName); - } else { - Info->VolumeLabel[0] =3D L'\0'; + StrCpyS (Info->VolumeLabel, VolNameLength + 1, VolumeName); + + FreePool (VolumeName); + + *BufferSize =3D NeededLength; + + return EFI_SUCCESS; +} + +/** + Retrieves the volume label and stores it in the EFI_FILE_SYSTEM_VOLUME_= LABEL format. + + @param[in] Part Pointer to the opened partition. + @param[out] Info Pointer to a EFI_FILE_SYSTEM_VOLUME_LABE= L. + @param[in out] BufferSize Pointer to the buffer size + + @return Status of the file information request. +**/ +STATIC +EFI_STATUS +Ext4GetVolumeLabelInfo ( + IN EXT4_PARTITION *Part, + OUT EFI_FILE_SYSTEM_VOLUME_LABEL *Info, + IN OUT UINTN *BufferSize + ) +{ + // Length of s_volume_name + null terminator + CHAR16 *VolumeName; + UINTN VolNameLength; + EFI_STATUS Status; + UINTN NeededLength; + + Status =3D Ext4GetVolumeName (Part, &VolumeName, &VolNameLength); + + if (EFI_ERROR (Status)) { + return Status; } =20 - if (VolumeName !=3D NULL) { + NeededLength =3D (VolNameLength + 1) * sizeof (CHAR16); + + if (NeededLength > *BufferSize) { + *BufferSize =3D NeededLength; + FreePool (VolumeName); + + return EFI_BUFFER_TOO_SMALL; } =20 + Status =3D StrCpyS (Info->VolumeLabel, VolNameLength + 1, VolumeName); + + ASSERT_EFI_ERROR (Status); + + FreePool (VolumeName); + *BufferSize =3D NeededLength; =20 return EFI_SUCCESS; @@ -674,12 +753,20 @@ Ext4GetInfo ( OUT VOID *Buffer ) { + EXT4_PARTITION *Partition; + + Partition =3D ((EXT4_FILE *)This)->Partition; + if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { return Ext4GetFileInfo ((EXT4_FILE *)This, Buffer, BufferSize); } =20 if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { - return Ext4GetFilesystemInfo (((EXT4_FILE *)This)->Partition, Buffer, = BufferSize); + return Ext4GetFilesystemInfo (Partition, Buffer, BufferSize); + } + + if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid))= { + return Ext4GetVolumeLabelInfo (Partition, Buffer, BufferSize); } =20 return EFI_UNSUPPORTED; --=20 2.33.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#79665): https://edk2.groups.io/g/devel/message/79665 Mute This Topic: https://groups.io/mt/85043014/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Sat May 4 16:21:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+79666+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+79666+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1629557304; cv=none; d=zohomail.com; s=zohoarc; b=ftDP1Zh1Qx6MLKpbp2CcSk9qA7WUtEhAtkR3N2KiVF7VVdyTSpQ6j3yU3liTnHRgYYIzkE/aKYBlYCoiAubFo5pftXmtpqEH9/U6vrEAdm0ebeYAxuP8fjG5GRRfXkHTglrjBJPaow4noYujZQx8K1QSkDppnGpiMyy+y9h7wwQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1629557304; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=RNSBJD+fpDeEubaHcVruVksujePv8uWtLWBnuch5tF0=; b=Pc64bnVNqVA6QTZzrcHEstcCnz7n4NZzEm93Ev+ccMx9ppfdwp1HLXW3cv2UL+os+pez0wmr9SrP7AybSTX7DwhcQr04wKrNP9mesJ8FVqCR25r5MerTuEDa7nRkrVLG4Qio1o+uhPzsqHxkWqqeTkxD3awmYuUMaU6+cFADJSA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+79666+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1629557304689603.7467115444781; Sat, 21 Aug 2021 07:48:24 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id lce5YY1788612x3y5YgTs3GJ; Sat, 21 Aug 2021 07:48:24 -0700 X-Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) by mx.groups.io with SMTP id smtpd.web09.11633.1629557303527170107 for ; Sat, 21 Aug 2021 07:48:23 -0700 X-Received: by mail-wm1-f54.google.com with SMTP id f10so7639148wml.2 for ; Sat, 21 Aug 2021 07:48:23 -0700 (PDT) X-Gm-Message-State: 7glV3vkOE4tZaacPqaDTlRgXx1787277AA= X-Google-Smtp-Source: ABdhPJyx7L1J5udP3fOV4djgAKm6HQ1m00lFvpzjxhiEgm3T+Ia3COjZ/e50v9Mz/l+dZuaJWAGOTw== X-Received: by 2002:a7b:c756:: with SMTP id w22mr8646139wmk.169.1629557301950; Sat, 21 Aug 2021 07:48:21 -0700 (PDT) X-Received: from PC-PEDRO.lan (bl8-253-151.dsl.telepac.pt. [85.241.253.151]) by smtp.gmail.com with ESMTPSA id j17sm9118036wrt.69.2021.08.21.07.48.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Aug 2021 07:48:21 -0700 (PDT) From: "Pedro Falcato" To: devel@edk2.groups.io Cc: Pedro Falcato , Leif Lindholm , Michael D Kinney , Bret Barkelew Subject: [edk2-devel] [edk2-platforms PATCH v2 5/5] Ext4Pkg: Sanity check more EXT4_DIR_ENTRY values. Date: Sat, 21 Aug 2021 15:47:10 +0100 Message-Id: <20210821144711.39546-6-pedro.falcato@gmail.com> In-Reply-To: <20210821144711.39546-1-pedro.falcato@gmail.com> References: <20210821144711.39546-1-pedro.falcato@gmail.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pedro.falcato@gmail.com Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1629557304; bh=uOrupqxXTqpB4r4Txk6gc3fyyiRHx4bPwZqYjsMwASQ=; h=Cc:Date:From:Reply-To:Subject:To; b=E/mj5bbP6KUmT/dW43iSq4XNCo+YfSMjoPO9sTggdkw0jX+zgGrx57EQd3cVBVISFSh NoO+EDUyeh/oWTBWdKrdiBEUlWlLS6TC5xDGKirIetbFeybACE9MMIHIxAZfHct8XKT7a AND3KDlZmTDPtJ9O43KTssvf2tgJEg4hpT8= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1629557305287100017 Content-Type: text/plain; charset="utf-8" This should close up some possible exploits using crafted filesystem images. Cc: Leif Lindholm Cc: Michael D Kinney Cc: Bret Barkelew Signed-off-by: Pedro Falcato Reviewed-by: Michael D Kinney --- Features/Ext4Pkg/Ext4Dxe/Directory.c | 90 ++++++++++++++++------------ 1 file changed, 51 insertions(+), 39 deletions(-) diff --git a/Features/Ext4Pkg/Ext4Dxe/Directory.c b/Features/Ext4Pkg/Ext4Dx= e/Directory.c index 7d1b2dcfe524..102c82f05da0 100644 --- a/Features/Ext4Pkg/Ext4Dxe/Directory.c +++ b/Features/Ext4Pkg/Ext4Dxe/Directory.c @@ -50,6 +50,37 @@ Ext4GetUcs2DirentName ( return Status; } =20 +/** + Validates a directory entry. + + @param[in] Dirent Pointer to the directory entry. + + @retval TRUE Valid directory entry. + FALSE Invalid directory entry. +**/ +STATIC +BOOLEAN +Ext4ValidDirent ( + IN CONST EXT4_DIR_ENTRY *Dirent + ) +{ + UINTN RequiredSize; + + RequiredSize =3D Dirent->name_len + EXT4_MIN_DIR_ENTRY_LEN; + + if (Dirent->rec_len < RequiredSize) { + DEBUG ((DEBUG_ERROR, "[ext4] dirent size %lu too small (compared to %l= u)\n", Dirent->rec_len, RequiredSize)); + return FALSE; + } + + // Dirent sizes need to be 4 byte aligned + if (Dirent->rec_len % 4) { + return FALSE; + } + + return TRUE; +} + /** Retrieves a directory entry. =20 @@ -75,11 +106,11 @@ Ext4RetrieveDirent ( UINT64 DirInoSize; UINT32 BlockRemainder; UINTN Length; - CHAR8 *BufPtr; EXT4_DIR_ENTRY *Entry; UINTN RemainingBlock; CHAR16 DirentUcs2Name[EXT4_NAME_MAX + 1]; UINTN ToCopy; + UINTN BlockOffset; =20 Status =3D EFI_NOT_FOUND; Buf =3D AllocatePool (Partition->BlockSize); @@ -109,14 +140,19 @@ Ext4RetrieveDirent ( return Status; } =20 - for (BufPtr =3D Buf; BufPtr < Buf + Partition->BlockSize; ) { - Entry =3D (EXT4_DIR_ENTRY *)BufPtr; - if (Entry->rec_len =3D=3D 0) { + for (BlockOffset =3D 0; BlockOffset < Partition->BlockSize; ) { + Entry =3D (EXT4_DIR_ENTRY *)(Buf + BlockOffset); + RemainingBlock =3D Partition->BlockSize - BlockOffset; + // Check if the minimum directory entry fits inside [BlockOffset, En= dOfBlock] + if (RemainingBlock < EXT4_MIN_DIR_ENTRY_LEN) { FreePool (Buf); return EFI_VOLUME_CORRUPTED; } =20 - RemainingBlock =3D Partition->BlockSize - (BufPtr - Buf); + if (!Ext4ValidDirent (Entry)) { + FreePool (Buf); + return EFI_VOLUME_CORRUPTED; + } =20 if (Entry->name_len > RemainingBlock || Entry->rec_len > RemainingBl= ock) { // Corrupted filesystem @@ -131,12 +167,13 @@ Ext4RetrieveDirent ( 2) Linux and a number of BSDs also have a filename limit of 255. */ if (Entry->name_len > EXT4_NAME_MAX) { + BlockOffset +=3D Entry->rec_len; continue; } =20 // Unused entry if (Entry->inode =3D=3D 0) { - BufPtr +=3D Entry->rec_len; + BlockOffset +=3D Entry->rec_len; continue; } =20 @@ -150,7 +187,7 @@ Ext4RetrieveDirent ( if (EFI_ERROR (Status)) { // If we error out, skip this entry // I'm not sure if this is correct behaviour, but I don't think th= ere's a precedent here. - BufPtr +=3D Entry->rec_len; + BlockOffset +=3D Entry->rec_len; continue; } =20 @@ -163,7 +200,7 @@ Ext4RetrieveDirent ( return EFI_SUCCESS; } =20 - BufPtr +=3D Entry->rec_len; + BlockOffset +=3D Entry->rec_len; } =20 Off +=3D Partition->BlockSize; @@ -379,37 +416,6 @@ Ext4OpenVolume ( return EFI_SUCCESS; } =20 -/** - Validates a directory entry. - - @param[in] Dirent Pointer to the directory entry. - - @retval TRUE Valid directory entry. - FALSE Invalid directory entry. -**/ -STATIC -BOOLEAN -Ext4ValidDirent ( - IN CONST EXT4_DIR_ENTRY *Dirent - ) -{ - UINTN RequiredSize; - - RequiredSize =3D Dirent->name_len + EXT4_MIN_DIR_ENTRY_LEN; - - if (Dirent->rec_len < RequiredSize) { - DEBUG ((DEBUG_ERROR, "[ext4] dirent size %lu too small (compared to %l= u)\n", Dirent->rec_len, RequiredSize)); - return FALSE; - } - - // Dirent sizes need to be 4 byte aligned - if (Dirent->rec_len % 4) { - return FALSE; - } - - return TRUE; -} - /** Reads a directory entry. =20 @@ -481,6 +487,12 @@ Ext4ReadDir ( goto Out; } =20 + // Check if the entire dir entry length fits in Len + if (Len < EXT4_MIN_DIR_ENTRY_LEN + Entry.name_len) { + Status =3D EFI_VOLUME_CORRUPTED; + goto Out; + } + // We don't care about passing . or .. entries to the caller of ReadDi= r(), // since they're generally useless entries *and* may break things if t= oo // many callers assume FAT32. --=20 2.33.0 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#79666): https://edk2.groups.io/g/devel/message/79666 Mute This Topic: https://groups.io/mt/85043015/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-