summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHelge Deller <deller@gmx.de>2022-04-01 17:23:18 +0200
committerHelge Deller <deller@gmx.de>2022-04-01 23:13:57 +0200
commit500bef7f3886417679c35b60be2cadd16bf9a746 (patch)
treeba8c0747ef0968e10581b562b9605ba59ba8943d
parent593d83117d50d6c53a8cc2347659385e40abd3d0 (diff)
downloadpalo-500bef7f3886417679c35b60be2cadd16bf9a746.tar.gz
Fix palo to list all entries from the /boot directory
I noticed that palo randomly doesn't list all available files in the /boot directory. This is caused by palo accessing non-aligned 32-bit words and due to the absense of unalignment fixup routines wrong values are returned for such words. This is what happens: The directory entry structure for ext2 is defined as: struct ext2_dir_entry_2 { __u32 inode; /* Inode number */ __u16 rec_len; /* Directory entry length */ __u8 name_len; /* Name length */ __u8 file_type; char name[EXT2_NAME_LEN]; /* File name */ The inode member is of type __u32, so the compiler will access it with a 32-bit load instruction. The problem here is, that this __u32 might not be word-aligned. We are in the bootloader which doesn't has an unalignment-handler, so depending on the CPU undefined values can be returned, mostly often zero. This patch fixes it by copying the directory entry to a naturally aligned struct before accessing it with word accesses. Fixes: 812b3b323186 ("Remove useless files from directory listing") Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r--ipl/ext2.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/ipl/ext2.c b/ipl/ext2.c
index 8a96b9b..1b77c2d 100644
--- a/ipl/ext2.c
+++ b/ipl/ext2.c
@@ -209,8 +209,12 @@ static void swapino(struct ext2_inode *i)
#endif
}
-static void swapde(struct ext2_dir_entry_2 *de)
+static struct ext2_dir_entry_2 de_temp;
+static struct ext2_dir_entry_2 *swapde(struct ext2_dir_entry_2 *source)
{
+ struct ext2_dir_entry_2 *de = &de_temp;
+
+ memcpy(de, source, sizeof(de_temp));
if (Debug) printf("swapde: 0x%x 0x%x / ",
de->inode, de->rec_len);
inplace(__le32_to_cpu, de->inode);
@@ -219,6 +223,7 @@ static void swapde(struct ext2_dir_entry_2 *de)
de->inode, de->rec_len,
de->name_len, de->file_type,
de->name_len, de->name);
+ return de;
}
static struct ext2_group_desc *ext2_gds(int i)
@@ -750,7 +755,7 @@ static struct ext2_dir_entry_2 *ext2_readdiri(struct ext2_inode *dir_inode,
}
dp = (struct ext2_dir_entry_2 *) (blkbuf + blockoffset);
- swapde(dp);
+ dp = swapde(dp);
blockoffset += dp->rec_len;
/* ext2 deletes a file by zeroing its inode. We skip deleted
* files, corrupt entries and entries that aren't a regular