diff options
author | Helge Deller <deller@gmx.de> | 2022-04-01 17:23:18 +0200 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2022-04-01 23:13:57 +0200 |
commit | 500bef7f3886417679c35b60be2cadd16bf9a746 (patch) | |
tree | ba8c0747ef0968e10581b562b9605ba59ba8943d | |
parent | 593d83117d50d6c53a8cc2347659385e40abd3d0 (diff) | |
download | palo-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.c | 9 |
1 files changed, 7 insertions, 2 deletions
@@ -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 |