diff options
author | Anton Kling <anton@kling.gg> | 2023-11-09 23:20:58 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2023-11-09 23:22:26 +0100 |
commit | 240e715aed9ea8b1a6d3b89c84cf9af3c3436e6f (patch) | |
tree | 7ec621054b9722b218a0788f527271e7020149f8 /kernel/fs/ext2.c | |
parent | 606a45e15dbb72a3870cd173884e2299afc72e8e (diff) |
Kernel/fs: Dynamically allocate depending upon file size of directory.
This also solves a bug where the data_p pointer could get out of range
due to incorrect assumptions being made about the ext2 directory layout.
To be fair even a faulty ext2 directory layout should not be able to
cause memory bugs.
Diffstat (limited to 'kernel/fs/ext2.c')
-rw-r--r-- | kernel/fs/ext2.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c index bd0fb07..b4d7716 100644 --- a/kernel/fs/ext2.c +++ b/kernel/fs/ext2.c @@ -165,14 +165,20 @@ void ext2_write_inode(int inode_index, inode_t *data) { int ext2_get_inode_in_directory(int dir_inode, char *file, direntry_header_t *entry) { - // FIXME: Allocate sufficent size each time - unsigned char *data = kmalloc(block_byte_size * 5); + uint64_t file_size; + ASSERT_BUT_FIXME_PROPOGATE(-1 != + read_inode(dir_inode, NULL, 0, 0, &file_size)); + uint64_t allocation_size = file_size; + unsigned char *data = kmalloc(allocation_size); ASSERT_BUT_FIXME_PROPOGATE( - -1 != read_inode(dir_inode, data, block_byte_size * 5, 0, 0)); + -1 != read_inode(dir_inode, data, allocation_size, 0, NULL)); direntry_header_t *dir; unsigned char *data_p = data; - for (; (dir = (direntry_header_t *)data_p)->inode; data_p += dir->size) { + unsigned char *data_end = data + allocation_size; + for (; data_p <= (data_end - sizeof(direntry_header_t)) && + (dir = (direntry_header_t *)data_p)->inode; + data_p += dir->size) { if (0 == dir->size) break; if (0 == dir->name_length) |