Commit 3eb8e74ec72736b9b9d728bad30484ec89c91dde
Committed by
Linus Torvalds
1 parent
658c74cf3c
Exists in
master
and in
7 other branches
fs/partitions/efi.c: corrupted GUID partition tables can cause kernel oops
The kernel automatically evaluates partition tables of storage devices. The code for evaluating GUID partitions (in fs/partitions/efi.c) contains a bug that causes a kernel oops on certain corrupted GUID partition tables. This bug has security impacts, because it allows, for example, to prepare a storage device that crashes a kernel subsystem upon connecting the device (e.g., a "USB Stick of (Partial) Death"). crc = efi_crc32((const unsigned char *) (*gpt), le32_to_cpu((*gpt)->header_size)); computes a CRC32 checksum over gpt covering (*gpt)->header_size bytes. There is no validation of (*gpt)->header_size before the efi_crc32 call. A corrupted partition table may have large values for (*gpt)->header_size. In this case, the CRC32 computation access memory beyond the memory allocated for gpt, which may cause a kernel heap overflow. Validate value of GUID partition table header size. [akpm@linux-foundation.org: fix layout and indenting] Signed-off-by: Timo Warns <warns@pre-sense.de> Cc: Matt Domsch <Matt_Domsch@dell.com> Cc: Eugene Teo <eugeneteo@kernel.sg> Cc: Dave Jones <davej@codemonkey.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 9 additions and 0 deletions Inline Diff
fs/partitions/efi.c
1 | /************************************************************ | 1 | /************************************************************ |
2 | * EFI GUID Partition Table handling | 2 | * EFI GUID Partition Table handling |
3 | * | 3 | * |
4 | * http://www.uefi.org/specs/ | 4 | * http://www.uefi.org/specs/ |
5 | * http://www.intel.com/technology/efi/ | 5 | * http://www.intel.com/technology/efi/ |
6 | * | 6 | * |
7 | * efi.[ch] by Matt Domsch <Matt_Domsch@dell.com> | 7 | * efi.[ch] by Matt Domsch <Matt_Domsch@dell.com> |
8 | * Copyright 2000,2001,2002,2004 Dell Inc. | 8 | * Copyright 2000,2001,2002,2004 Dell Inc. |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
12 | * the Free Software Foundation; either version 2 of the License, or | 12 | * the Free Software Foundation; either version 2 of the License, or |
13 | * (at your option) any later version. | 13 | * (at your option) any later version. |
14 | * | 14 | * |
15 | * This program is distributed in the hope that it will be useful, | 15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | * GNU General Public License for more details. | 18 | * GNU General Public License for more details. |
19 | * | 19 | * |
20 | * You should have received a copy of the GNU General Public License | 20 | * You should have received a copy of the GNU General Public License |
21 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 | * | 23 | * |
24 | * | 24 | * |
25 | * TODO: | 25 | * TODO: |
26 | * | 26 | * |
27 | * Changelog: | 27 | * Changelog: |
28 | * Mon Nov 09 2004 Matt Domsch <Matt_Domsch@dell.com> | 28 | * Mon Nov 09 2004 Matt Domsch <Matt_Domsch@dell.com> |
29 | * - test for valid PMBR and valid PGPT before ever reading | 29 | * - test for valid PMBR and valid PGPT before ever reading |
30 | * AGPT, allow override with 'gpt' kernel command line option. | 30 | * AGPT, allow override with 'gpt' kernel command line option. |
31 | * - check for first/last_usable_lba outside of size of disk | 31 | * - check for first/last_usable_lba outside of size of disk |
32 | * | 32 | * |
33 | * Tue Mar 26 2002 Matt Domsch <Matt_Domsch@dell.com> | 33 | * Tue Mar 26 2002 Matt Domsch <Matt_Domsch@dell.com> |
34 | * - Ported to 2.5.7-pre1 and 2.5.7-dj2 | 34 | * - Ported to 2.5.7-pre1 and 2.5.7-dj2 |
35 | * - Applied patch to avoid fault in alternate header handling | 35 | * - Applied patch to avoid fault in alternate header handling |
36 | * - cleaned up find_valid_gpt | 36 | * - cleaned up find_valid_gpt |
37 | * - On-disk structure and copy in memory is *always* LE now - | 37 | * - On-disk structure and copy in memory is *always* LE now - |
38 | * swab fields as needed | 38 | * swab fields as needed |
39 | * - remove print_gpt_header() | 39 | * - remove print_gpt_header() |
40 | * - only use first max_p partition entries, to keep the kernel minor number | 40 | * - only use first max_p partition entries, to keep the kernel minor number |
41 | * and partition numbers tied. | 41 | * and partition numbers tied. |
42 | * | 42 | * |
43 | * Mon Feb 04 2002 Matt Domsch <Matt_Domsch@dell.com> | 43 | * Mon Feb 04 2002 Matt Domsch <Matt_Domsch@dell.com> |
44 | * - Removed __PRIPTR_PREFIX - not being used | 44 | * - Removed __PRIPTR_PREFIX - not being used |
45 | * | 45 | * |
46 | * Mon Jan 14 2002 Matt Domsch <Matt_Domsch@dell.com> | 46 | * Mon Jan 14 2002 Matt Domsch <Matt_Domsch@dell.com> |
47 | * - Ported to 2.5.2-pre11 + library crc32 patch Linus applied | 47 | * - Ported to 2.5.2-pre11 + library crc32 patch Linus applied |
48 | * | 48 | * |
49 | * Thu Dec 6 2001 Matt Domsch <Matt_Domsch@dell.com> | 49 | * Thu Dec 6 2001 Matt Domsch <Matt_Domsch@dell.com> |
50 | * - Added compare_gpts(). | 50 | * - Added compare_gpts(). |
51 | * - moved le_efi_guid_to_cpus() back into this file. GPT is the only | 51 | * - moved le_efi_guid_to_cpus() back into this file. GPT is the only |
52 | * thing that keeps EFI GUIDs on disk. | 52 | * thing that keeps EFI GUIDs on disk. |
53 | * - Changed gpt structure names and members to be simpler and more Linux-like. | 53 | * - Changed gpt structure names and members to be simpler and more Linux-like. |
54 | * | 54 | * |
55 | * Wed Oct 17 2001 Matt Domsch <Matt_Domsch@dell.com> | 55 | * Wed Oct 17 2001 Matt Domsch <Matt_Domsch@dell.com> |
56 | * - Removed CONFIG_DEVFS_VOLUMES_UUID code entirely per Martin Wilck | 56 | * - Removed CONFIG_DEVFS_VOLUMES_UUID code entirely per Martin Wilck |
57 | * | 57 | * |
58 | * Wed Oct 10 2001 Matt Domsch <Matt_Domsch@dell.com> | 58 | * Wed Oct 10 2001 Matt Domsch <Matt_Domsch@dell.com> |
59 | * - Changed function comments to DocBook style per Andreas Dilger suggestion. | 59 | * - Changed function comments to DocBook style per Andreas Dilger suggestion. |
60 | * | 60 | * |
61 | * Mon Oct 08 2001 Matt Domsch <Matt_Domsch@dell.com> | 61 | * Mon Oct 08 2001 Matt Domsch <Matt_Domsch@dell.com> |
62 | * - Change read_lba() to use the page cache per Al Viro's work. | 62 | * - Change read_lba() to use the page cache per Al Viro's work. |
63 | * - print u64s properly on all architectures | 63 | * - print u64s properly on all architectures |
64 | * - fixed debug_printk(), now Dprintk() | 64 | * - fixed debug_printk(), now Dprintk() |
65 | * | 65 | * |
66 | * Mon Oct 01 2001 Matt Domsch <Matt_Domsch@dell.com> | 66 | * Mon Oct 01 2001 Matt Domsch <Matt_Domsch@dell.com> |
67 | * - Style cleanups | 67 | * - Style cleanups |
68 | * - made most functions static | 68 | * - made most functions static |
69 | * - Endianness addition | 69 | * - Endianness addition |
70 | * - remove test for second alternate header, as it's not per spec, | 70 | * - remove test for second alternate header, as it's not per spec, |
71 | * and is unnecessary. There's now a method to read/write the last | 71 | * and is unnecessary. There's now a method to read/write the last |
72 | * sector of an odd-sized disk from user space. No tools have ever | 72 | * sector of an odd-sized disk from user space. No tools have ever |
73 | * been released which used this code, so it's effectively dead. | 73 | * been released which used this code, so it's effectively dead. |
74 | * - Per Asit Mallick of Intel, added a test for a valid PMBR. | 74 | * - Per Asit Mallick of Intel, added a test for a valid PMBR. |
75 | * - Added kernel command line option 'gpt' to override valid PMBR test. | 75 | * - Added kernel command line option 'gpt' to override valid PMBR test. |
76 | * | 76 | * |
77 | * Wed Jun 6 2001 Martin Wilck <Martin.Wilck@Fujitsu-Siemens.com> | 77 | * Wed Jun 6 2001 Martin Wilck <Martin.Wilck@Fujitsu-Siemens.com> |
78 | * - added devfs volume UUID support (/dev/volumes/uuids) for | 78 | * - added devfs volume UUID support (/dev/volumes/uuids) for |
79 | * mounting file systems by the partition GUID. | 79 | * mounting file systems by the partition GUID. |
80 | * | 80 | * |
81 | * Tue Dec 5 2000 Matt Domsch <Matt_Domsch@dell.com> | 81 | * Tue Dec 5 2000 Matt Domsch <Matt_Domsch@dell.com> |
82 | * - Moved crc32() to linux/lib, added efi_crc32(). | 82 | * - Moved crc32() to linux/lib, added efi_crc32(). |
83 | * | 83 | * |
84 | * Thu Nov 30 2000 Matt Domsch <Matt_Domsch@dell.com> | 84 | * Thu Nov 30 2000 Matt Domsch <Matt_Domsch@dell.com> |
85 | * - Replaced Intel's CRC32 function with an equivalent | 85 | * - Replaced Intel's CRC32 function with an equivalent |
86 | * non-license-restricted version. | 86 | * non-license-restricted version. |
87 | * | 87 | * |
88 | * Wed Oct 25 2000 Matt Domsch <Matt_Domsch@dell.com> | 88 | * Wed Oct 25 2000 Matt Domsch <Matt_Domsch@dell.com> |
89 | * - Fixed the last_lba() call to return the proper last block | 89 | * - Fixed the last_lba() call to return the proper last block |
90 | * | 90 | * |
91 | * Thu Oct 12 2000 Matt Domsch <Matt_Domsch@dell.com> | 91 | * Thu Oct 12 2000 Matt Domsch <Matt_Domsch@dell.com> |
92 | * - Thanks to Andries Brouwer for his debugging assistance. | 92 | * - Thanks to Andries Brouwer for his debugging assistance. |
93 | * - Code works, detects all the partitions. | 93 | * - Code works, detects all the partitions. |
94 | * | 94 | * |
95 | ************************************************************/ | 95 | ************************************************************/ |
96 | #include <linux/crc32.h> | 96 | #include <linux/crc32.h> |
97 | #include <linux/ctype.h> | 97 | #include <linux/ctype.h> |
98 | #include <linux/math64.h> | 98 | #include <linux/math64.h> |
99 | #include <linux/slab.h> | 99 | #include <linux/slab.h> |
100 | #include "check.h" | 100 | #include "check.h" |
101 | #include "efi.h" | 101 | #include "efi.h" |
102 | 102 | ||
103 | /* This allows a kernel command line option 'gpt' to override | 103 | /* This allows a kernel command line option 'gpt' to override |
104 | * the test for invalid PMBR. Not __initdata because reloading | 104 | * the test for invalid PMBR. Not __initdata because reloading |
105 | * the partition tables happens after init too. | 105 | * the partition tables happens after init too. |
106 | */ | 106 | */ |
107 | static int force_gpt; | 107 | static int force_gpt; |
108 | static int __init | 108 | static int __init |
109 | force_gpt_fn(char *str) | 109 | force_gpt_fn(char *str) |
110 | { | 110 | { |
111 | force_gpt = 1; | 111 | force_gpt = 1; |
112 | return 1; | 112 | return 1; |
113 | } | 113 | } |
114 | __setup("gpt", force_gpt_fn); | 114 | __setup("gpt", force_gpt_fn); |
115 | 115 | ||
116 | 116 | ||
117 | /** | 117 | /** |
118 | * efi_crc32() - EFI version of crc32 function | 118 | * efi_crc32() - EFI version of crc32 function |
119 | * @buf: buffer to calculate crc32 of | 119 | * @buf: buffer to calculate crc32 of |
120 | * @len - length of buf | 120 | * @len - length of buf |
121 | * | 121 | * |
122 | * Description: Returns EFI-style CRC32 value for @buf | 122 | * Description: Returns EFI-style CRC32 value for @buf |
123 | * | 123 | * |
124 | * This function uses the little endian Ethernet polynomial | 124 | * This function uses the little endian Ethernet polynomial |
125 | * but seeds the function with ~0, and xor's with ~0 at the end. | 125 | * but seeds the function with ~0, and xor's with ~0 at the end. |
126 | * Note, the EFI Specification, v1.02, has a reference to | 126 | * Note, the EFI Specification, v1.02, has a reference to |
127 | * Dr. Dobbs Journal, May 1994 (actually it's in May 1992). | 127 | * Dr. Dobbs Journal, May 1994 (actually it's in May 1992). |
128 | */ | 128 | */ |
129 | static inline u32 | 129 | static inline u32 |
130 | efi_crc32(const void *buf, unsigned long len) | 130 | efi_crc32(const void *buf, unsigned long len) |
131 | { | 131 | { |
132 | return (crc32(~0L, buf, len) ^ ~0L); | 132 | return (crc32(~0L, buf, len) ^ ~0L); |
133 | } | 133 | } |
134 | 134 | ||
135 | /** | 135 | /** |
136 | * last_lba(): return number of last logical block of device | 136 | * last_lba(): return number of last logical block of device |
137 | * @bdev: block device | 137 | * @bdev: block device |
138 | * | 138 | * |
139 | * Description: Returns last LBA value on success, 0 on error. | 139 | * Description: Returns last LBA value on success, 0 on error. |
140 | * This is stored (by sd and ide-geometry) in | 140 | * This is stored (by sd and ide-geometry) in |
141 | * the part[0] entry for this disk, and is the number of | 141 | * the part[0] entry for this disk, and is the number of |
142 | * physical sectors available on the disk. | 142 | * physical sectors available on the disk. |
143 | */ | 143 | */ |
144 | static u64 last_lba(struct block_device *bdev) | 144 | static u64 last_lba(struct block_device *bdev) |
145 | { | 145 | { |
146 | if (!bdev || !bdev->bd_inode) | 146 | if (!bdev || !bdev->bd_inode) |
147 | return 0; | 147 | return 0; |
148 | return div_u64(bdev->bd_inode->i_size, | 148 | return div_u64(bdev->bd_inode->i_size, |
149 | bdev_logical_block_size(bdev)) - 1ULL; | 149 | bdev_logical_block_size(bdev)) - 1ULL; |
150 | } | 150 | } |
151 | 151 | ||
152 | static inline int | 152 | static inline int |
153 | pmbr_part_valid(struct partition *part) | 153 | pmbr_part_valid(struct partition *part) |
154 | { | 154 | { |
155 | if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT && | 155 | if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT && |
156 | le32_to_cpu(part->start_sect) == 1UL) | 156 | le32_to_cpu(part->start_sect) == 1UL) |
157 | return 1; | 157 | return 1; |
158 | return 0; | 158 | return 0; |
159 | } | 159 | } |
160 | 160 | ||
161 | /** | 161 | /** |
162 | * is_pmbr_valid(): test Protective MBR for validity | 162 | * is_pmbr_valid(): test Protective MBR for validity |
163 | * @mbr: pointer to a legacy mbr structure | 163 | * @mbr: pointer to a legacy mbr structure |
164 | * | 164 | * |
165 | * Description: Returns 1 if PMBR is valid, 0 otherwise. | 165 | * Description: Returns 1 if PMBR is valid, 0 otherwise. |
166 | * Validity depends on two things: | 166 | * Validity depends on two things: |
167 | * 1) MSDOS signature is in the last two bytes of the MBR | 167 | * 1) MSDOS signature is in the last two bytes of the MBR |
168 | * 2) One partition of type 0xEE is found | 168 | * 2) One partition of type 0xEE is found |
169 | */ | 169 | */ |
170 | static int | 170 | static int |
171 | is_pmbr_valid(legacy_mbr *mbr) | 171 | is_pmbr_valid(legacy_mbr *mbr) |
172 | { | 172 | { |
173 | int i; | 173 | int i; |
174 | if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE) | 174 | if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE) |
175 | return 0; | 175 | return 0; |
176 | for (i = 0; i < 4; i++) | 176 | for (i = 0; i < 4; i++) |
177 | if (pmbr_part_valid(&mbr->partition_record[i])) | 177 | if (pmbr_part_valid(&mbr->partition_record[i])) |
178 | return 1; | 178 | return 1; |
179 | return 0; | 179 | return 0; |
180 | } | 180 | } |
181 | 181 | ||
182 | /** | 182 | /** |
183 | * read_lba(): Read bytes from disk, starting at given LBA | 183 | * read_lba(): Read bytes from disk, starting at given LBA |
184 | * @state | 184 | * @state |
185 | * @lba | 185 | * @lba |
186 | * @buffer | 186 | * @buffer |
187 | * @size_t | 187 | * @size_t |
188 | * | 188 | * |
189 | * Description: Reads @count bytes from @state->bdev into @buffer. | 189 | * Description: Reads @count bytes from @state->bdev into @buffer. |
190 | * Returns number of bytes read on success, 0 on error. | 190 | * Returns number of bytes read on success, 0 on error. |
191 | */ | 191 | */ |
192 | static size_t read_lba(struct parsed_partitions *state, | 192 | static size_t read_lba(struct parsed_partitions *state, |
193 | u64 lba, u8 *buffer, size_t count) | 193 | u64 lba, u8 *buffer, size_t count) |
194 | { | 194 | { |
195 | size_t totalreadcount = 0; | 195 | size_t totalreadcount = 0; |
196 | struct block_device *bdev = state->bdev; | 196 | struct block_device *bdev = state->bdev; |
197 | sector_t n = lba * (bdev_logical_block_size(bdev) / 512); | 197 | sector_t n = lba * (bdev_logical_block_size(bdev) / 512); |
198 | 198 | ||
199 | if (!buffer || lba > last_lba(bdev)) | 199 | if (!buffer || lba > last_lba(bdev)) |
200 | return 0; | 200 | return 0; |
201 | 201 | ||
202 | while (count) { | 202 | while (count) { |
203 | int copied = 512; | 203 | int copied = 512; |
204 | Sector sect; | 204 | Sector sect; |
205 | unsigned char *data = read_part_sector(state, n++, §); | 205 | unsigned char *data = read_part_sector(state, n++, §); |
206 | if (!data) | 206 | if (!data) |
207 | break; | 207 | break; |
208 | if (copied > count) | 208 | if (copied > count) |
209 | copied = count; | 209 | copied = count; |
210 | memcpy(buffer, data, copied); | 210 | memcpy(buffer, data, copied); |
211 | put_dev_sector(sect); | 211 | put_dev_sector(sect); |
212 | buffer += copied; | 212 | buffer += copied; |
213 | totalreadcount +=copied; | 213 | totalreadcount +=copied; |
214 | count -= copied; | 214 | count -= copied; |
215 | } | 215 | } |
216 | return totalreadcount; | 216 | return totalreadcount; |
217 | } | 217 | } |
218 | 218 | ||
219 | /** | 219 | /** |
220 | * alloc_read_gpt_entries(): reads partition entries from disk | 220 | * alloc_read_gpt_entries(): reads partition entries from disk |
221 | * @state | 221 | * @state |
222 | * @gpt - GPT header | 222 | * @gpt - GPT header |
223 | * | 223 | * |
224 | * Description: Returns ptes on success, NULL on error. | 224 | * Description: Returns ptes on success, NULL on error. |
225 | * Allocates space for PTEs based on information found in @gpt. | 225 | * Allocates space for PTEs based on information found in @gpt. |
226 | * Notes: remember to free pte when you're done! | 226 | * Notes: remember to free pte when you're done! |
227 | */ | 227 | */ |
228 | static gpt_entry *alloc_read_gpt_entries(struct parsed_partitions *state, | 228 | static gpt_entry *alloc_read_gpt_entries(struct parsed_partitions *state, |
229 | gpt_header *gpt) | 229 | gpt_header *gpt) |
230 | { | 230 | { |
231 | size_t count; | 231 | size_t count; |
232 | gpt_entry *pte; | 232 | gpt_entry *pte; |
233 | 233 | ||
234 | if (!gpt) | 234 | if (!gpt) |
235 | return NULL; | 235 | return NULL; |
236 | 236 | ||
237 | count = le32_to_cpu(gpt->num_partition_entries) * | 237 | count = le32_to_cpu(gpt->num_partition_entries) * |
238 | le32_to_cpu(gpt->sizeof_partition_entry); | 238 | le32_to_cpu(gpt->sizeof_partition_entry); |
239 | if (!count) | 239 | if (!count) |
240 | return NULL; | 240 | return NULL; |
241 | pte = kzalloc(count, GFP_KERNEL); | 241 | pte = kzalloc(count, GFP_KERNEL); |
242 | if (!pte) | 242 | if (!pte) |
243 | return NULL; | 243 | return NULL; |
244 | 244 | ||
245 | if (read_lba(state, le64_to_cpu(gpt->partition_entry_lba), | 245 | if (read_lba(state, le64_to_cpu(gpt->partition_entry_lba), |
246 | (u8 *) pte, | 246 | (u8 *) pte, |
247 | count) < count) { | 247 | count) < count) { |
248 | kfree(pte); | 248 | kfree(pte); |
249 | pte=NULL; | 249 | pte=NULL; |
250 | return NULL; | 250 | return NULL; |
251 | } | 251 | } |
252 | return pte; | 252 | return pte; |
253 | } | 253 | } |
254 | 254 | ||
255 | /** | 255 | /** |
256 | * alloc_read_gpt_header(): Allocates GPT header, reads into it from disk | 256 | * alloc_read_gpt_header(): Allocates GPT header, reads into it from disk |
257 | * @state | 257 | * @state |
258 | * @lba is the Logical Block Address of the partition table | 258 | * @lba is the Logical Block Address of the partition table |
259 | * | 259 | * |
260 | * Description: returns GPT header on success, NULL on error. Allocates | 260 | * Description: returns GPT header on success, NULL on error. Allocates |
261 | * and fills a GPT header starting at @ from @state->bdev. | 261 | * and fills a GPT header starting at @ from @state->bdev. |
262 | * Note: remember to free gpt when finished with it. | 262 | * Note: remember to free gpt when finished with it. |
263 | */ | 263 | */ |
264 | static gpt_header *alloc_read_gpt_header(struct parsed_partitions *state, | 264 | static gpt_header *alloc_read_gpt_header(struct parsed_partitions *state, |
265 | u64 lba) | 265 | u64 lba) |
266 | { | 266 | { |
267 | gpt_header *gpt; | 267 | gpt_header *gpt; |
268 | unsigned ssz = bdev_logical_block_size(state->bdev); | 268 | unsigned ssz = bdev_logical_block_size(state->bdev); |
269 | 269 | ||
270 | gpt = kzalloc(ssz, GFP_KERNEL); | 270 | gpt = kzalloc(ssz, GFP_KERNEL); |
271 | if (!gpt) | 271 | if (!gpt) |
272 | return NULL; | 272 | return NULL; |
273 | 273 | ||
274 | if (read_lba(state, lba, (u8 *) gpt, ssz) < ssz) { | 274 | if (read_lba(state, lba, (u8 *) gpt, ssz) < ssz) { |
275 | kfree(gpt); | 275 | kfree(gpt); |
276 | gpt=NULL; | 276 | gpt=NULL; |
277 | return NULL; | 277 | return NULL; |
278 | } | 278 | } |
279 | 279 | ||
280 | return gpt; | 280 | return gpt; |
281 | } | 281 | } |
282 | 282 | ||
283 | /** | 283 | /** |
284 | * is_gpt_valid() - tests one GPT header and PTEs for validity | 284 | * is_gpt_valid() - tests one GPT header and PTEs for validity |
285 | * @state | 285 | * @state |
286 | * @lba is the logical block address of the GPT header to test | 286 | * @lba is the logical block address of the GPT header to test |
287 | * @gpt is a GPT header ptr, filled on return. | 287 | * @gpt is a GPT header ptr, filled on return. |
288 | * @ptes is a PTEs ptr, filled on return. | 288 | * @ptes is a PTEs ptr, filled on return. |
289 | * | 289 | * |
290 | * Description: returns 1 if valid, 0 on error. | 290 | * Description: returns 1 if valid, 0 on error. |
291 | * If valid, returns pointers to newly allocated GPT header and PTEs. | 291 | * If valid, returns pointers to newly allocated GPT header and PTEs. |
292 | */ | 292 | */ |
293 | static int is_gpt_valid(struct parsed_partitions *state, u64 lba, | 293 | static int is_gpt_valid(struct parsed_partitions *state, u64 lba, |
294 | gpt_header **gpt, gpt_entry **ptes) | 294 | gpt_header **gpt, gpt_entry **ptes) |
295 | { | 295 | { |
296 | u32 crc, origcrc; | 296 | u32 crc, origcrc; |
297 | u64 lastlba; | 297 | u64 lastlba; |
298 | 298 | ||
299 | if (!ptes) | 299 | if (!ptes) |
300 | return 0; | 300 | return 0; |
301 | if (!(*gpt = alloc_read_gpt_header(state, lba))) | 301 | if (!(*gpt = alloc_read_gpt_header(state, lba))) |
302 | return 0; | 302 | return 0; |
303 | 303 | ||
304 | /* Check the GUID Partition Table signature */ | 304 | /* Check the GUID Partition Table signature */ |
305 | if (le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) { | 305 | if (le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) { |
306 | pr_debug("GUID Partition Table Header signature is wrong:" | 306 | pr_debug("GUID Partition Table Header signature is wrong:" |
307 | "%lld != %lld\n", | 307 | "%lld != %lld\n", |
308 | (unsigned long long)le64_to_cpu((*gpt)->signature), | 308 | (unsigned long long)le64_to_cpu((*gpt)->signature), |
309 | (unsigned long long)GPT_HEADER_SIGNATURE); | 309 | (unsigned long long)GPT_HEADER_SIGNATURE); |
310 | goto fail; | 310 | goto fail; |
311 | } | 311 | } |
312 | 312 | ||
313 | /* Check the GUID Partition Table header size */ | ||
314 | if (le32_to_cpu((*gpt)->header_size) > | ||
315 | bdev_logical_block_size(state->bdev)) { | ||
316 | pr_debug("GUID Partition Table Header size is wrong: %u > %u\n", | ||
317 | le32_to_cpu((*gpt)->header_size), | ||
318 | bdev_logical_block_size(state->bdev)); | ||
319 | goto fail; | ||
320 | } | ||
321 | |||
313 | /* Check the GUID Partition Table CRC */ | 322 | /* Check the GUID Partition Table CRC */ |
314 | origcrc = le32_to_cpu((*gpt)->header_crc32); | 323 | origcrc = le32_to_cpu((*gpt)->header_crc32); |
315 | (*gpt)->header_crc32 = 0; | 324 | (*gpt)->header_crc32 = 0; |
316 | crc = efi_crc32((const unsigned char *) (*gpt), le32_to_cpu((*gpt)->header_size)); | 325 | crc = efi_crc32((const unsigned char *) (*gpt), le32_to_cpu((*gpt)->header_size)); |
317 | 326 | ||
318 | if (crc != origcrc) { | 327 | if (crc != origcrc) { |
319 | pr_debug("GUID Partition Table Header CRC is wrong: %x != %x\n", | 328 | pr_debug("GUID Partition Table Header CRC is wrong: %x != %x\n", |
320 | crc, origcrc); | 329 | crc, origcrc); |
321 | goto fail; | 330 | goto fail; |
322 | } | 331 | } |
323 | (*gpt)->header_crc32 = cpu_to_le32(origcrc); | 332 | (*gpt)->header_crc32 = cpu_to_le32(origcrc); |
324 | 333 | ||
325 | /* Check that the my_lba entry points to the LBA that contains | 334 | /* Check that the my_lba entry points to the LBA that contains |
326 | * the GUID Partition Table */ | 335 | * the GUID Partition Table */ |
327 | if (le64_to_cpu((*gpt)->my_lba) != lba) { | 336 | if (le64_to_cpu((*gpt)->my_lba) != lba) { |
328 | pr_debug("GPT my_lba incorrect: %lld != %lld\n", | 337 | pr_debug("GPT my_lba incorrect: %lld != %lld\n", |
329 | (unsigned long long)le64_to_cpu((*gpt)->my_lba), | 338 | (unsigned long long)le64_to_cpu((*gpt)->my_lba), |
330 | (unsigned long long)lba); | 339 | (unsigned long long)lba); |
331 | goto fail; | 340 | goto fail; |
332 | } | 341 | } |
333 | 342 | ||
334 | /* Check the first_usable_lba and last_usable_lba are | 343 | /* Check the first_usable_lba and last_usable_lba are |
335 | * within the disk. | 344 | * within the disk. |
336 | */ | 345 | */ |
337 | lastlba = last_lba(state->bdev); | 346 | lastlba = last_lba(state->bdev); |
338 | if (le64_to_cpu((*gpt)->first_usable_lba) > lastlba) { | 347 | if (le64_to_cpu((*gpt)->first_usable_lba) > lastlba) { |
339 | pr_debug("GPT: first_usable_lba incorrect: %lld > %lld\n", | 348 | pr_debug("GPT: first_usable_lba incorrect: %lld > %lld\n", |
340 | (unsigned long long)le64_to_cpu((*gpt)->first_usable_lba), | 349 | (unsigned long long)le64_to_cpu((*gpt)->first_usable_lba), |
341 | (unsigned long long)lastlba); | 350 | (unsigned long long)lastlba); |
342 | goto fail; | 351 | goto fail; |
343 | } | 352 | } |
344 | if (le64_to_cpu((*gpt)->last_usable_lba) > lastlba) { | 353 | if (le64_to_cpu((*gpt)->last_usable_lba) > lastlba) { |
345 | pr_debug("GPT: last_usable_lba incorrect: %lld > %lld\n", | 354 | pr_debug("GPT: last_usable_lba incorrect: %lld > %lld\n", |
346 | (unsigned long long)le64_to_cpu((*gpt)->last_usable_lba), | 355 | (unsigned long long)le64_to_cpu((*gpt)->last_usable_lba), |
347 | (unsigned long long)lastlba); | 356 | (unsigned long long)lastlba); |
348 | goto fail; | 357 | goto fail; |
349 | } | 358 | } |
350 | 359 | ||
351 | /* Check that sizeof_partition_entry has the correct value */ | 360 | /* Check that sizeof_partition_entry has the correct value */ |
352 | if (le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) { | 361 | if (le32_to_cpu((*gpt)->sizeof_partition_entry) != sizeof(gpt_entry)) { |
353 | pr_debug("GUID Partitition Entry Size check failed.\n"); | 362 | pr_debug("GUID Partitition Entry Size check failed.\n"); |
354 | goto fail; | 363 | goto fail; |
355 | } | 364 | } |
356 | 365 | ||
357 | if (!(*ptes = alloc_read_gpt_entries(state, *gpt))) | 366 | if (!(*ptes = alloc_read_gpt_entries(state, *gpt))) |
358 | goto fail; | 367 | goto fail; |
359 | 368 | ||
360 | /* Check the GUID Partition Entry Array CRC */ | 369 | /* Check the GUID Partition Entry Array CRC */ |
361 | crc = efi_crc32((const unsigned char *) (*ptes), | 370 | crc = efi_crc32((const unsigned char *) (*ptes), |
362 | le32_to_cpu((*gpt)->num_partition_entries) * | 371 | le32_to_cpu((*gpt)->num_partition_entries) * |
363 | le32_to_cpu((*gpt)->sizeof_partition_entry)); | 372 | le32_to_cpu((*gpt)->sizeof_partition_entry)); |
364 | 373 | ||
365 | if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) { | 374 | if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) { |
366 | pr_debug("GUID Partitition Entry Array CRC check failed.\n"); | 375 | pr_debug("GUID Partitition Entry Array CRC check failed.\n"); |
367 | goto fail_ptes; | 376 | goto fail_ptes; |
368 | } | 377 | } |
369 | 378 | ||
370 | /* We're done, all's well */ | 379 | /* We're done, all's well */ |
371 | return 1; | 380 | return 1; |
372 | 381 | ||
373 | fail_ptes: | 382 | fail_ptes: |
374 | kfree(*ptes); | 383 | kfree(*ptes); |
375 | *ptes = NULL; | 384 | *ptes = NULL; |
376 | fail: | 385 | fail: |
377 | kfree(*gpt); | 386 | kfree(*gpt); |
378 | *gpt = NULL; | 387 | *gpt = NULL; |
379 | return 0; | 388 | return 0; |
380 | } | 389 | } |
381 | 390 | ||
382 | /** | 391 | /** |
383 | * is_pte_valid() - tests one PTE for validity | 392 | * is_pte_valid() - tests one PTE for validity |
384 | * @pte is the pte to check | 393 | * @pte is the pte to check |
385 | * @lastlba is last lba of the disk | 394 | * @lastlba is last lba of the disk |
386 | * | 395 | * |
387 | * Description: returns 1 if valid, 0 on error. | 396 | * Description: returns 1 if valid, 0 on error. |
388 | */ | 397 | */ |
389 | static inline int | 398 | static inline int |
390 | is_pte_valid(const gpt_entry *pte, const u64 lastlba) | 399 | is_pte_valid(const gpt_entry *pte, const u64 lastlba) |
391 | { | 400 | { |
392 | if ((!efi_guidcmp(pte->partition_type_guid, NULL_GUID)) || | 401 | if ((!efi_guidcmp(pte->partition_type_guid, NULL_GUID)) || |
393 | le64_to_cpu(pte->starting_lba) > lastlba || | 402 | le64_to_cpu(pte->starting_lba) > lastlba || |
394 | le64_to_cpu(pte->ending_lba) > lastlba) | 403 | le64_to_cpu(pte->ending_lba) > lastlba) |
395 | return 0; | 404 | return 0; |
396 | return 1; | 405 | return 1; |
397 | } | 406 | } |
398 | 407 | ||
399 | /** | 408 | /** |
400 | * compare_gpts() - Search disk for valid GPT headers and PTEs | 409 | * compare_gpts() - Search disk for valid GPT headers and PTEs |
401 | * @pgpt is the primary GPT header | 410 | * @pgpt is the primary GPT header |
402 | * @agpt is the alternate GPT header | 411 | * @agpt is the alternate GPT header |
403 | * @lastlba is the last LBA number | 412 | * @lastlba is the last LBA number |
404 | * Description: Returns nothing. Sanity checks pgpt and agpt fields | 413 | * Description: Returns nothing. Sanity checks pgpt and agpt fields |
405 | * and prints warnings on discrepancies. | 414 | * and prints warnings on discrepancies. |
406 | * | 415 | * |
407 | */ | 416 | */ |
408 | static void | 417 | static void |
409 | compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba) | 418 | compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba) |
410 | { | 419 | { |
411 | int error_found = 0; | 420 | int error_found = 0; |
412 | if (!pgpt || !agpt) | 421 | if (!pgpt || !agpt) |
413 | return; | 422 | return; |
414 | if (le64_to_cpu(pgpt->my_lba) != le64_to_cpu(agpt->alternate_lba)) { | 423 | if (le64_to_cpu(pgpt->my_lba) != le64_to_cpu(agpt->alternate_lba)) { |
415 | printk(KERN_WARNING | 424 | printk(KERN_WARNING |
416 | "GPT:Primary header LBA != Alt. header alternate_lba\n"); | 425 | "GPT:Primary header LBA != Alt. header alternate_lba\n"); |
417 | printk(KERN_WARNING "GPT:%lld != %lld\n", | 426 | printk(KERN_WARNING "GPT:%lld != %lld\n", |
418 | (unsigned long long)le64_to_cpu(pgpt->my_lba), | 427 | (unsigned long long)le64_to_cpu(pgpt->my_lba), |
419 | (unsigned long long)le64_to_cpu(agpt->alternate_lba)); | 428 | (unsigned long long)le64_to_cpu(agpt->alternate_lba)); |
420 | error_found++; | 429 | error_found++; |
421 | } | 430 | } |
422 | if (le64_to_cpu(pgpt->alternate_lba) != le64_to_cpu(agpt->my_lba)) { | 431 | if (le64_to_cpu(pgpt->alternate_lba) != le64_to_cpu(agpt->my_lba)) { |
423 | printk(KERN_WARNING | 432 | printk(KERN_WARNING |
424 | "GPT:Primary header alternate_lba != Alt. header my_lba\n"); | 433 | "GPT:Primary header alternate_lba != Alt. header my_lba\n"); |
425 | printk(KERN_WARNING "GPT:%lld != %lld\n", | 434 | printk(KERN_WARNING "GPT:%lld != %lld\n", |
426 | (unsigned long long)le64_to_cpu(pgpt->alternate_lba), | 435 | (unsigned long long)le64_to_cpu(pgpt->alternate_lba), |
427 | (unsigned long long)le64_to_cpu(agpt->my_lba)); | 436 | (unsigned long long)le64_to_cpu(agpt->my_lba)); |
428 | error_found++; | 437 | error_found++; |
429 | } | 438 | } |
430 | if (le64_to_cpu(pgpt->first_usable_lba) != | 439 | if (le64_to_cpu(pgpt->first_usable_lba) != |
431 | le64_to_cpu(agpt->first_usable_lba)) { | 440 | le64_to_cpu(agpt->first_usable_lba)) { |
432 | printk(KERN_WARNING "GPT:first_usable_lbas don't match.\n"); | 441 | printk(KERN_WARNING "GPT:first_usable_lbas don't match.\n"); |
433 | printk(KERN_WARNING "GPT:%lld != %lld\n", | 442 | printk(KERN_WARNING "GPT:%lld != %lld\n", |
434 | (unsigned long long)le64_to_cpu(pgpt->first_usable_lba), | 443 | (unsigned long long)le64_to_cpu(pgpt->first_usable_lba), |
435 | (unsigned long long)le64_to_cpu(agpt->first_usable_lba)); | 444 | (unsigned long long)le64_to_cpu(agpt->first_usable_lba)); |
436 | error_found++; | 445 | error_found++; |
437 | } | 446 | } |
438 | if (le64_to_cpu(pgpt->last_usable_lba) != | 447 | if (le64_to_cpu(pgpt->last_usable_lba) != |
439 | le64_to_cpu(agpt->last_usable_lba)) { | 448 | le64_to_cpu(agpt->last_usable_lba)) { |
440 | printk(KERN_WARNING "GPT:last_usable_lbas don't match.\n"); | 449 | printk(KERN_WARNING "GPT:last_usable_lbas don't match.\n"); |
441 | printk(KERN_WARNING "GPT:%lld != %lld\n", | 450 | printk(KERN_WARNING "GPT:%lld != %lld\n", |
442 | (unsigned long long)le64_to_cpu(pgpt->last_usable_lba), | 451 | (unsigned long long)le64_to_cpu(pgpt->last_usable_lba), |
443 | (unsigned long long)le64_to_cpu(agpt->last_usable_lba)); | 452 | (unsigned long long)le64_to_cpu(agpt->last_usable_lba)); |
444 | error_found++; | 453 | error_found++; |
445 | } | 454 | } |
446 | if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) { | 455 | if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) { |
447 | printk(KERN_WARNING "GPT:disk_guids don't match.\n"); | 456 | printk(KERN_WARNING "GPT:disk_guids don't match.\n"); |
448 | error_found++; | 457 | error_found++; |
449 | } | 458 | } |
450 | if (le32_to_cpu(pgpt->num_partition_entries) != | 459 | if (le32_to_cpu(pgpt->num_partition_entries) != |
451 | le32_to_cpu(agpt->num_partition_entries)) { | 460 | le32_to_cpu(agpt->num_partition_entries)) { |
452 | printk(KERN_WARNING "GPT:num_partition_entries don't match: " | 461 | printk(KERN_WARNING "GPT:num_partition_entries don't match: " |
453 | "0x%x != 0x%x\n", | 462 | "0x%x != 0x%x\n", |
454 | le32_to_cpu(pgpt->num_partition_entries), | 463 | le32_to_cpu(pgpt->num_partition_entries), |
455 | le32_to_cpu(agpt->num_partition_entries)); | 464 | le32_to_cpu(agpt->num_partition_entries)); |
456 | error_found++; | 465 | error_found++; |
457 | } | 466 | } |
458 | if (le32_to_cpu(pgpt->sizeof_partition_entry) != | 467 | if (le32_to_cpu(pgpt->sizeof_partition_entry) != |
459 | le32_to_cpu(agpt->sizeof_partition_entry)) { | 468 | le32_to_cpu(agpt->sizeof_partition_entry)) { |
460 | printk(KERN_WARNING | 469 | printk(KERN_WARNING |
461 | "GPT:sizeof_partition_entry values don't match: " | 470 | "GPT:sizeof_partition_entry values don't match: " |
462 | "0x%x != 0x%x\n", | 471 | "0x%x != 0x%x\n", |
463 | le32_to_cpu(pgpt->sizeof_partition_entry), | 472 | le32_to_cpu(pgpt->sizeof_partition_entry), |
464 | le32_to_cpu(agpt->sizeof_partition_entry)); | 473 | le32_to_cpu(agpt->sizeof_partition_entry)); |
465 | error_found++; | 474 | error_found++; |
466 | } | 475 | } |
467 | if (le32_to_cpu(pgpt->partition_entry_array_crc32) != | 476 | if (le32_to_cpu(pgpt->partition_entry_array_crc32) != |
468 | le32_to_cpu(agpt->partition_entry_array_crc32)) { | 477 | le32_to_cpu(agpt->partition_entry_array_crc32)) { |
469 | printk(KERN_WARNING | 478 | printk(KERN_WARNING |
470 | "GPT:partition_entry_array_crc32 values don't match: " | 479 | "GPT:partition_entry_array_crc32 values don't match: " |
471 | "0x%x != 0x%x\n", | 480 | "0x%x != 0x%x\n", |
472 | le32_to_cpu(pgpt->partition_entry_array_crc32), | 481 | le32_to_cpu(pgpt->partition_entry_array_crc32), |
473 | le32_to_cpu(agpt->partition_entry_array_crc32)); | 482 | le32_to_cpu(agpt->partition_entry_array_crc32)); |
474 | error_found++; | 483 | error_found++; |
475 | } | 484 | } |
476 | if (le64_to_cpu(pgpt->alternate_lba) != lastlba) { | 485 | if (le64_to_cpu(pgpt->alternate_lba) != lastlba) { |
477 | printk(KERN_WARNING | 486 | printk(KERN_WARNING |
478 | "GPT:Primary header thinks Alt. header is not at the end of the disk.\n"); | 487 | "GPT:Primary header thinks Alt. header is not at the end of the disk.\n"); |
479 | printk(KERN_WARNING "GPT:%lld != %lld\n", | 488 | printk(KERN_WARNING "GPT:%lld != %lld\n", |
480 | (unsigned long long)le64_to_cpu(pgpt->alternate_lba), | 489 | (unsigned long long)le64_to_cpu(pgpt->alternate_lba), |
481 | (unsigned long long)lastlba); | 490 | (unsigned long long)lastlba); |
482 | error_found++; | 491 | error_found++; |
483 | } | 492 | } |
484 | 493 | ||
485 | if (le64_to_cpu(agpt->my_lba) != lastlba) { | 494 | if (le64_to_cpu(agpt->my_lba) != lastlba) { |
486 | printk(KERN_WARNING | 495 | printk(KERN_WARNING |
487 | "GPT:Alternate GPT header not at the end of the disk.\n"); | 496 | "GPT:Alternate GPT header not at the end of the disk.\n"); |
488 | printk(KERN_WARNING "GPT:%lld != %lld\n", | 497 | printk(KERN_WARNING "GPT:%lld != %lld\n", |
489 | (unsigned long long)le64_to_cpu(agpt->my_lba), | 498 | (unsigned long long)le64_to_cpu(agpt->my_lba), |
490 | (unsigned long long)lastlba); | 499 | (unsigned long long)lastlba); |
491 | error_found++; | 500 | error_found++; |
492 | } | 501 | } |
493 | 502 | ||
494 | if (error_found) | 503 | if (error_found) |
495 | printk(KERN_WARNING | 504 | printk(KERN_WARNING |
496 | "GPT: Use GNU Parted to correct GPT errors.\n"); | 505 | "GPT: Use GNU Parted to correct GPT errors.\n"); |
497 | return; | 506 | return; |
498 | } | 507 | } |
499 | 508 | ||
500 | /** | 509 | /** |
501 | * find_valid_gpt() - Search disk for valid GPT headers and PTEs | 510 | * find_valid_gpt() - Search disk for valid GPT headers and PTEs |
502 | * @state | 511 | * @state |
503 | * @gpt is a GPT header ptr, filled on return. | 512 | * @gpt is a GPT header ptr, filled on return. |
504 | * @ptes is a PTEs ptr, filled on return. | 513 | * @ptes is a PTEs ptr, filled on return. |
505 | * Description: Returns 1 if valid, 0 on error. | 514 | * Description: Returns 1 if valid, 0 on error. |
506 | * If valid, returns pointers to newly allocated GPT header and PTEs. | 515 | * If valid, returns pointers to newly allocated GPT header and PTEs. |
507 | * Validity depends on PMBR being valid (or being overridden by the | 516 | * Validity depends on PMBR being valid (or being overridden by the |
508 | * 'gpt' kernel command line option) and finding either the Primary | 517 | * 'gpt' kernel command line option) and finding either the Primary |
509 | * GPT header and PTEs valid, or the Alternate GPT header and PTEs | 518 | * GPT header and PTEs valid, or the Alternate GPT header and PTEs |
510 | * valid. If the Primary GPT header is not valid, the Alternate GPT header | 519 | * valid. If the Primary GPT header is not valid, the Alternate GPT header |
511 | * is not checked unless the 'gpt' kernel command line option is passed. | 520 | * is not checked unless the 'gpt' kernel command line option is passed. |
512 | * This protects against devices which misreport their size, and forces | 521 | * This protects against devices which misreport their size, and forces |
513 | * the user to decide to use the Alternate GPT. | 522 | * the user to decide to use the Alternate GPT. |
514 | */ | 523 | */ |
515 | static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt, | 524 | static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt, |
516 | gpt_entry **ptes) | 525 | gpt_entry **ptes) |
517 | { | 526 | { |
518 | int good_pgpt = 0, good_agpt = 0, good_pmbr = 0; | 527 | int good_pgpt = 0, good_agpt = 0, good_pmbr = 0; |
519 | gpt_header *pgpt = NULL, *agpt = NULL; | 528 | gpt_header *pgpt = NULL, *agpt = NULL; |
520 | gpt_entry *pptes = NULL, *aptes = NULL; | 529 | gpt_entry *pptes = NULL, *aptes = NULL; |
521 | legacy_mbr *legacymbr; | 530 | legacy_mbr *legacymbr; |
522 | u64 lastlba; | 531 | u64 lastlba; |
523 | 532 | ||
524 | if (!ptes) | 533 | if (!ptes) |
525 | return 0; | 534 | return 0; |
526 | 535 | ||
527 | lastlba = last_lba(state->bdev); | 536 | lastlba = last_lba(state->bdev); |
528 | if (!force_gpt) { | 537 | if (!force_gpt) { |
529 | /* This will be added to the EFI Spec. per Intel after v1.02. */ | 538 | /* This will be added to the EFI Spec. per Intel after v1.02. */ |
530 | legacymbr = kzalloc(sizeof (*legacymbr), GFP_KERNEL); | 539 | legacymbr = kzalloc(sizeof (*legacymbr), GFP_KERNEL); |
531 | if (legacymbr) { | 540 | if (legacymbr) { |
532 | read_lba(state, 0, (u8 *) legacymbr, | 541 | read_lba(state, 0, (u8 *) legacymbr, |
533 | sizeof (*legacymbr)); | 542 | sizeof (*legacymbr)); |
534 | good_pmbr = is_pmbr_valid(legacymbr); | 543 | good_pmbr = is_pmbr_valid(legacymbr); |
535 | kfree(legacymbr); | 544 | kfree(legacymbr); |
536 | } | 545 | } |
537 | if (!good_pmbr) | 546 | if (!good_pmbr) |
538 | goto fail; | 547 | goto fail; |
539 | } | 548 | } |
540 | 549 | ||
541 | good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA, | 550 | good_pgpt = is_gpt_valid(state, GPT_PRIMARY_PARTITION_TABLE_LBA, |
542 | &pgpt, &pptes); | 551 | &pgpt, &pptes); |
543 | if (good_pgpt) | 552 | if (good_pgpt) |
544 | good_agpt = is_gpt_valid(state, | 553 | good_agpt = is_gpt_valid(state, |
545 | le64_to_cpu(pgpt->alternate_lba), | 554 | le64_to_cpu(pgpt->alternate_lba), |
546 | &agpt, &aptes); | 555 | &agpt, &aptes); |
547 | if (!good_agpt && force_gpt) | 556 | if (!good_agpt && force_gpt) |
548 | good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes); | 557 | good_agpt = is_gpt_valid(state, lastlba, &agpt, &aptes); |
549 | 558 | ||
550 | /* The obviously unsuccessful case */ | 559 | /* The obviously unsuccessful case */ |
551 | if (!good_pgpt && !good_agpt) | 560 | if (!good_pgpt && !good_agpt) |
552 | goto fail; | 561 | goto fail; |
553 | 562 | ||
554 | compare_gpts(pgpt, agpt, lastlba); | 563 | compare_gpts(pgpt, agpt, lastlba); |
555 | 564 | ||
556 | /* The good cases */ | 565 | /* The good cases */ |
557 | if (good_pgpt) { | 566 | if (good_pgpt) { |
558 | *gpt = pgpt; | 567 | *gpt = pgpt; |
559 | *ptes = pptes; | 568 | *ptes = pptes; |
560 | kfree(agpt); | 569 | kfree(agpt); |
561 | kfree(aptes); | 570 | kfree(aptes); |
562 | if (!good_agpt) { | 571 | if (!good_agpt) { |
563 | printk(KERN_WARNING | 572 | printk(KERN_WARNING |
564 | "Alternate GPT is invalid, " | 573 | "Alternate GPT is invalid, " |
565 | "using primary GPT.\n"); | 574 | "using primary GPT.\n"); |
566 | } | 575 | } |
567 | return 1; | 576 | return 1; |
568 | } | 577 | } |
569 | else if (good_agpt) { | 578 | else if (good_agpt) { |
570 | *gpt = agpt; | 579 | *gpt = agpt; |
571 | *ptes = aptes; | 580 | *ptes = aptes; |
572 | kfree(pgpt); | 581 | kfree(pgpt); |
573 | kfree(pptes); | 582 | kfree(pptes); |
574 | printk(KERN_WARNING | 583 | printk(KERN_WARNING |
575 | "Primary GPT is invalid, using alternate GPT.\n"); | 584 | "Primary GPT is invalid, using alternate GPT.\n"); |
576 | return 1; | 585 | return 1; |
577 | } | 586 | } |
578 | 587 | ||
579 | fail: | 588 | fail: |
580 | kfree(pgpt); | 589 | kfree(pgpt); |
581 | kfree(agpt); | 590 | kfree(agpt); |
582 | kfree(pptes); | 591 | kfree(pptes); |
583 | kfree(aptes); | 592 | kfree(aptes); |
584 | *gpt = NULL; | 593 | *gpt = NULL; |
585 | *ptes = NULL; | 594 | *ptes = NULL; |
586 | return 0; | 595 | return 0; |
587 | } | 596 | } |
588 | 597 | ||
589 | /** | 598 | /** |
590 | * efi_partition(struct parsed_partitions *state) | 599 | * efi_partition(struct parsed_partitions *state) |
591 | * @state | 600 | * @state |
592 | * | 601 | * |
593 | * Description: called from check.c, if the disk contains GPT | 602 | * Description: called from check.c, if the disk contains GPT |
594 | * partitions, sets up partition entries in the kernel. | 603 | * partitions, sets up partition entries in the kernel. |
595 | * | 604 | * |
596 | * If the first block on the disk is a legacy MBR, | 605 | * If the first block on the disk is a legacy MBR, |
597 | * it will get handled by msdos_partition(). | 606 | * it will get handled by msdos_partition(). |
598 | * If it's a Protective MBR, we'll handle it here. | 607 | * If it's a Protective MBR, we'll handle it here. |
599 | * | 608 | * |
600 | * We do not create a Linux partition for GPT, but | 609 | * We do not create a Linux partition for GPT, but |
601 | * only for the actual data partitions. | 610 | * only for the actual data partitions. |
602 | * Returns: | 611 | * Returns: |
603 | * -1 if unable to read the partition table | 612 | * -1 if unable to read the partition table |
604 | * 0 if this isn't our partition table | 613 | * 0 if this isn't our partition table |
605 | * 1 if successful | 614 | * 1 if successful |
606 | * | 615 | * |
607 | */ | 616 | */ |
608 | int efi_partition(struct parsed_partitions *state) | 617 | int efi_partition(struct parsed_partitions *state) |
609 | { | 618 | { |
610 | gpt_header *gpt = NULL; | 619 | gpt_header *gpt = NULL; |
611 | gpt_entry *ptes = NULL; | 620 | gpt_entry *ptes = NULL; |
612 | u32 i; | 621 | u32 i; |
613 | unsigned ssz = bdev_logical_block_size(state->bdev) / 512; | 622 | unsigned ssz = bdev_logical_block_size(state->bdev) / 512; |
614 | u8 unparsed_guid[37]; | 623 | u8 unparsed_guid[37]; |
615 | 624 | ||
616 | if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { | 625 | if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { |
617 | kfree(gpt); | 626 | kfree(gpt); |
618 | kfree(ptes); | 627 | kfree(ptes); |
619 | return 0; | 628 | return 0; |
620 | } | 629 | } |
621 | 630 | ||
622 | pr_debug("GUID Partition Table is valid! Yea!\n"); | 631 | pr_debug("GUID Partition Table is valid! Yea!\n"); |
623 | 632 | ||
624 | for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) { | 633 | for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) { |
625 | struct partition_meta_info *info; | 634 | struct partition_meta_info *info; |
626 | unsigned label_count = 0; | 635 | unsigned label_count = 0; |
627 | unsigned label_max; | 636 | unsigned label_max; |
628 | u64 start = le64_to_cpu(ptes[i].starting_lba); | 637 | u64 start = le64_to_cpu(ptes[i].starting_lba); |
629 | u64 size = le64_to_cpu(ptes[i].ending_lba) - | 638 | u64 size = le64_to_cpu(ptes[i].ending_lba) - |
630 | le64_to_cpu(ptes[i].starting_lba) + 1ULL; | 639 | le64_to_cpu(ptes[i].starting_lba) + 1ULL; |
631 | 640 | ||
632 | if (!is_pte_valid(&ptes[i], last_lba(state->bdev))) | 641 | if (!is_pte_valid(&ptes[i], last_lba(state->bdev))) |
633 | continue; | 642 | continue; |
634 | 643 | ||
635 | put_partition(state, i+1, start * ssz, size * ssz); | 644 | put_partition(state, i+1, start * ssz, size * ssz); |
636 | 645 | ||
637 | /* If this is a RAID volume, tell md */ | 646 | /* If this is a RAID volume, tell md */ |
638 | if (!efi_guidcmp(ptes[i].partition_type_guid, | 647 | if (!efi_guidcmp(ptes[i].partition_type_guid, |
639 | PARTITION_LINUX_RAID_GUID)) | 648 | PARTITION_LINUX_RAID_GUID)) |
640 | state->parts[i + 1].flags = ADDPART_FLAG_RAID; | 649 | state->parts[i + 1].flags = ADDPART_FLAG_RAID; |
641 | 650 | ||
642 | info = &state->parts[i + 1].info; | 651 | info = &state->parts[i + 1].info; |
643 | /* Instead of doing a manual swap to big endian, reuse the | 652 | /* Instead of doing a manual swap to big endian, reuse the |
644 | * common ASCII hex format as the interim. | 653 | * common ASCII hex format as the interim. |
645 | */ | 654 | */ |
646 | efi_guid_unparse(&ptes[i].unique_partition_guid, unparsed_guid); | 655 | efi_guid_unparse(&ptes[i].unique_partition_guid, unparsed_guid); |
647 | part_pack_uuid(unparsed_guid, info->uuid); | 656 | part_pack_uuid(unparsed_guid, info->uuid); |
648 | 657 | ||
649 | /* Naively convert UTF16-LE to 7 bits. */ | 658 | /* Naively convert UTF16-LE to 7 bits. */ |
650 | label_max = min(sizeof(info->volname) - 1, | 659 | label_max = min(sizeof(info->volname) - 1, |
651 | sizeof(ptes[i].partition_name)); | 660 | sizeof(ptes[i].partition_name)); |
652 | info->volname[label_max] = 0; | 661 | info->volname[label_max] = 0; |
653 | while (label_count < label_max) { | 662 | while (label_count < label_max) { |
654 | u8 c = ptes[i].partition_name[label_count] & 0xff; | 663 | u8 c = ptes[i].partition_name[label_count] & 0xff; |
655 | if (c && !isprint(c)) | 664 | if (c && !isprint(c)) |
656 | c = '!'; | 665 | c = '!'; |
657 | info->volname[label_count] = c; | 666 | info->volname[label_count] = c; |
658 | label_count++; | 667 | label_count++; |
659 | } | 668 | } |
660 | state->parts[i + 1].has_info = true; | 669 | state->parts[i + 1].has_info = true; |
661 | } | 670 | } |
662 | kfree(ptes); | 671 | kfree(ptes); |
663 | kfree(gpt); | 672 | kfree(gpt); |
664 | strlcat(state->pp_buf, "\n", PAGE_SIZE); | 673 | strlcat(state->pp_buf, "\n", PAGE_SIZE); |
665 | return 1; | 674 | return 1; |
666 | } | 675 | } |
667 | 676 |