]> git.proxmox.com Git - grub2.git/blame - debian/patches/0088-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch
bump version to 2.06-13+pmx2
[grub2.git] / debian / patches / 0088-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch
CommitLineData
6671639d
JAK
1From 9561d7ef621e5e68f12bcd916252ef1c11e60366 Mon Sep 17 00:00:00 2001
2From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
3Date: Wed, 6 Apr 2022 18:49:09 +0530
4Subject: fs/f2fs: Do not read past the end of nat bitmap
5
6A corrupt f2fs filesystem could have a block offset or a bitmap
7offset that would cause us to read beyond the bounds of the nat
8bitmap.
9
10Introduce the nat_bitmap_size member in grub_f2fs_data which holds
11the size of nat bitmap.
12
13Set the size when loading the nat bitmap in nat_bitmap_ptr(), and
14catch when an invalid offset would create a pointer past the end of
15the allocated space.
16
17Check against the bitmap size in grub_f2fs_test_bit() test bit to avoid
18reading past the end of the nat bitmap.
19
20Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
21Signed-off-by: Daniel Axtens <dja@axtens.net>
22Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
23---
24 grub-core/fs/f2fs.c | 33 +++++++++++++++++++++++++++------
25 1 file changed, 27 insertions(+), 6 deletions(-)
26
27diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c
28index 63702214b..8898b235e 100644
29--- a/grub-core/fs/f2fs.c
30+++ b/grub-core/fs/f2fs.c
31@@ -122,6 +122,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
32 #define F2FS_INLINE_DOTS 0x10 /* File having implicit dot dentries. */
33
34 #define MAX_VOLUME_NAME 512
35+#define MAX_NAT_BITMAP_SIZE 3900
36
37 enum FILE_TYPE
38 {
39@@ -183,7 +184,7 @@ struct grub_f2fs_checkpoint
40 grub_uint32_t checksum_offset;
41 grub_uint64_t elapsed_time;
42 grub_uint8_t alloc_type[MAX_ACTIVE_LOGS];
43- grub_uint8_t sit_nat_version_bitmap[3900];
44+ grub_uint8_t sit_nat_version_bitmap[MAX_NAT_BITMAP_SIZE];
45 grub_uint32_t checksum;
46 } GRUB_PACKED;
47
48@@ -302,6 +303,7 @@ struct grub_f2fs_data
49
50 struct grub_f2fs_nat_journal nat_j;
51 char *nat_bitmap;
52+ grub_uint32_t nat_bitmap_size;
53
54 grub_disk_t disk;
55 struct grub_f2fs_node *inode;
56@@ -377,15 +379,20 @@ sum_blk_addr (struct grub_f2fs_data *data, int base, int type)
57 }
58
59 static void *
60-nat_bitmap_ptr (struct grub_f2fs_data *data)
61+nat_bitmap_ptr (struct grub_f2fs_data *data, grub_uint32_t *nat_bitmap_size)
62 {
63 struct grub_f2fs_checkpoint *ckpt = &data->ckpt;
64 grub_uint32_t offset;
65+ *nat_bitmap_size = MAX_NAT_BITMAP_SIZE;
66
67 if (grub_le_to_cpu32 (data->sblock.cp_payload) > 0)
68 return ckpt->sit_nat_version_bitmap;
69
70 offset = grub_le_to_cpu32 (ckpt->sit_ver_bitmap_bytesize);
71+ if (offset >= MAX_NAT_BITMAP_SIZE)
72+ return NULL;
73+
74+ *nat_bitmap_size = *nat_bitmap_size - offset;
75
76 return ckpt->sit_nat_version_bitmap + offset;
77 }
78@@ -438,11 +445,15 @@ grub_f2fs_crc_valid (grub_uint32_t blk_crc, void *buf, const grub_uint32_t len)
79 }
80
81 static int
82-grub_f2fs_test_bit (grub_uint32_t nr, const char *p)
83+grub_f2fs_test_bit (grub_uint32_t nr, const char *p, grub_uint32_t len)
84 {
85 int mask;
86+ grub_uint32_t shifted_nr = (nr >> 3);
87+
88+ if (shifted_nr >= len)
89+ return -1;
90
91- p += (nr >> 3);
92+ p += shifted_nr;
93 mask = 1 << (7 - (nr & 0x07));
94
95 return mask & *p;
96@@ -662,6 +673,7 @@ get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid)
97 grub_uint32_t seg_off, block_off, entry_off, block_addr;
98 grub_uint32_t blkaddr = 0;
99 grub_err_t err;
100+ int result_bit;
101
102 err = get_blkaddr_from_nat_journal (data, nid, &blkaddr);
103 if (err != GRUB_ERR_NONE)
104@@ -682,8 +694,15 @@ get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid)
105 ((seg_off * data->blocks_per_seg) << 1) +
106 (block_off & (data->blocks_per_seg - 1));
107
108- if (grub_f2fs_test_bit (block_off, data->nat_bitmap))
109+ result_bit = grub_f2fs_test_bit (block_off, data->nat_bitmap,
110+ data->nat_bitmap_size);
111+ if (result_bit > 0)
112 block_addr += data->blocks_per_seg;
113+ else if (result_bit == -1)
114+ {
115+ grub_free (nat_block);
116+ return 0;
117+ }
118
119 err = grub_f2fs_block_read (data, block_addr, nat_block);
120 if (err)
121@@ -833,7 +852,9 @@ grub_f2fs_mount (grub_disk_t disk)
122 if (err)
123 goto fail;
124
125- data->nat_bitmap = nat_bitmap_ptr (data);
126+ data->nat_bitmap = nat_bitmap_ptr (data, &data->nat_bitmap_size);
127+ if (data->nat_bitmap == NULL)
128+ goto fail;
129
130 err = get_nat_journal (data);
131 if (err)