Skip to content

Commit

Permalink
cboot-*: add patch for ext4 linear directory traversal
Browse files Browse the repository at this point in the history
The existing code wasn't handling multi-block directories
correctly.

Signed-off-by: Matt Madison <[email protected]>
  • Loading branch information
madisongh committed Jul 15, 2021
1 parent ba7470b commit f06ccb9
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 0 deletions.
1 change: 1 addition & 0 deletions recipes-bsp/cboot/cboot-t18x_32.5.0.bb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ SRC_URI = "${L4T_ALT_URI_BASE}/cboot_src_t18x.tbz2;downloadfilename=cboot_src_t1
file://0009-Add-machine-ID-to-kernel-command-line.patch \
file://0012-bmp-support-A-B-slots.patch \
file://0013-Fix-ext4-sparse-file-handling.patch \
file://0015-Fix-ext4-multi-block-linear-directory-traversal.patch \
"
SRC_URI[sha256sum] = "6da8ad60d302d222c09d56bc8f7e90e08592a0471f8bcbadb30268b3b0ad320f"

Expand Down
1 change: 1 addition & 0 deletions recipes-bsp/cboot/cboot-t19x_32.5.0.bb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ SRC_URI = "${L4T_ALT_URI_BASE}/cboot_src_t19x.tbz2;downloadfilename=cboot_src_t1
file://0012-bmp-support-A-B-slots.patch \
file://0013-Fix-ext4-sparse-file-handling.patch \
file://0014-extlinux-support-timeouts-under-1-sec.patch \
file://0015-Fix-ext4-multi-block-linear-directory-traversal.patch \
"

SRC_URI[sha256sum] = "80a5b0491d75ea8f2d5f49e93e6d5b4986c739ff29f62133585c2fe7880e8fa9"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
From 24c9aa3884fca1f2476a372b7ad7bbb848c594a6 Mon Sep 17 00:00:00 2001
From: Matt Madison <[email protected]>
Date: Thu, 15 Jul 2021 05:27:46 -0700
Subject: [PATCH] Fix ext4 multi-block linear directory traversal

Signed-off-by: Matt Madison <[email protected]>
---
bootloader/partner/common/lib/fs/ext4/ext4.c | 41 +++++++++++---------
1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/bootloader/partner/common/lib/fs/ext4/ext4.c b/bootloader/partner/common/lib/fs/ext4/ext4.c
index d57fb27..90d8537 100644
--- a/bootloader/partner/common/lib/fs/ext4/ext4.c
+++ b/bootloader/partner/common/lib/fs/ext4/ext4.c
@@ -405,20 +405,26 @@ fail:
static int lookup_linear_dir(ext2_t *ext2, struct ext2fs_dinode *dir_inode, const char *name, uint8_t *buf,
inodenum_t *inum)
{
- uint file_blocknum;
size_t namelen = strlen(name);
struct ext2fs_dir_entry_2 *ent;
uint32_t pos;
+ uint32_t nblocks, blocknum;
bool file_entry_found = false;
int err;
+#if LOCAL_TRACE
+ char namebuf[EXT2FS_MAX_NAME_LEN+1];
+#endif

LTRACE_ENTRY;

- file_blocknum = 0;
- for (;;) {
- err = ext4_read_data_from_extent(ext2, dir_inode, buf);
- if (err <= 0) {
- return -1;
+ nblocks = LE32(dir_inode->e2di_nblock);
+ LTRACEF("directory is %u blocks\n", nblocks);
+
+ for (blocknum = 0; blocknum < nblocks; blocknum++) {
+ err = get_extents_blk(ext2, dir_inode, blocknum, buf);
+ if (err != NO_ERROR) {
+ LTRACEF("err %d getting block %u\n", err, blocknum);
+ break;
}

/* walk through the directory entries, looking for the one that matches */
@@ -426,17 +432,23 @@ static int lookup_linear_dir(ext2_t *ext2, struct ext2fs_dinode *dir_inode, cons
while (pos < E2FS_BLOCK_SIZE(ext2->super_blk)) {

ent = (struct ext2fs_dir_entry_2 *)&buf[pos];
- LTRACEF("ent %d:%d: inode 0x%x, reclen %d, namelen %d, name: %s\n",
- file_blocknum, pos, LE32(ent->e2d_inode), LE16(ent->e2d_rec_len), ent->e2d_name_len, ent->e2d_name);
-
/* Exit if no more file entries are present */
if (LE16(ent->e2d_rec_len) == 0) {
- LTRACEF("record len 0\n");
+ LTRACEF("record len 0 in block %u\n", blocknum);
break;
}

+#if LOCAL_TRACE
+ memcpy(namebuf, ent->e2d_name, ent->e2d_name_len);
+ namebuf[ent->e2d_name_len] = '\0';
+
+ LTRACEF("ent %d:%d: inode 0x%x, reclen %d, namelen %u, name: %s\n",
+ blocknum, pos, LE32(ent->e2d_inode), LE16(ent->e2d_rec_len),
+ ent->e2d_name_len, namebuf);
+#endif
+
/* match */
- if (ent->e2d_name_len == namelen && memcmp(name, ent->e2d_name, ent->e2d_name_len) == 0) {
+ if (ent->e2d_name_len == namelen && memcmp(name, ent->e2d_name, namelen) == 0) {
*inum = LE32(ent->e2d_inode);
LTRACEF("match: inode %d\n", *inum);
file_entry_found = true;
@@ -450,13 +462,6 @@ static int lookup_linear_dir(ext2_t *ext2, struct ext2fs_dinode *dir_inode, cons
break;
}

- file_blocknum++;
-
- /* sanity check the directory. 4MB should be enough */
- if (file_blocknum > 1024) {
- TRACEF("Invalid file block num\n");
- return -1;
- }
}

return err;

0 comments on commit f06ccb9

Please sign in to comment.