1 /*
2
3 File: partnone.c
4
5 Copyright (C) 1998-2009 Christophe GRENIER <grenier@cgsecurity.org>
6
7 This software is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write the Free Software Foundation, Inc., 51
19 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 */
22
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #ifdef HAVE_STDLIB_H
30 #include <stdlib.h>
31 #endif
32 #ifdef HAVE_STRING_H
33 #include <string.h>
34 #endif
35 #include <ctype.h> /* tolower */
36 #include "types.h"
37 #include "common.h"
38 #include "fnctdsk.h"
39 #include "analyse.h"
40 #include "lang.h"
41 #include "intrf.h"
42 #include "bfs.h"
43 #include "bsd.h"
44 #include "btrfs.h"
45 #include "cramfs.h"
46 #include "exfat.h"
47 #include "ext2.h"
48 #include "fat.h"
49 #include "fat_common.h"
50 #include "fatx.h"
51 #include "f2fs_fs.h"
52 #include "f2fs.h"
53 #include "iso9660.h"
54 #include "iso.h"
55 #include "gfs2.h"
56 #include "hfs.h"
57 #include "hfsp.h"
58 #include "hpfs.h"
59 #include "jfs_superblock.h"
60 #include "jfs.h"
61 #include "luks.h"
62 #include "lvm.h"
63 #include "md.h"
64 #include "netware.h"
65 #include "ntfs.h"
66 #include "refs.h"
67 #include "rfs.h"
68 #include "sun.h"
69 #include "sysv.h"
70 #include "swap.h"
71 #include "ufs.h"
72 #include "xfs.h"
73 #include "vmfs.h"
74 #include "wbfs.h"
75 #include "zfs.h"
76 #include "log.h"
77
78 static int check_part_none(disk_t *disk_car, const int verbose,partition_t *partition,const int saveheader);
79 static int get_geometry_from_nonembr(const unsigned char *buffer, const int verbose, CHSgeometry_t *geometry);
80 static list_part_t *read_part_none(disk_t *disk_car, const int verbose, const int saveheader);
81 static list_part_t *init_part_order_none(const disk_t *disk_car, list_part_t *list_part);
82 static void set_next_status_none(const disk_t *disk_car, partition_t *partition);
83 static int test_structure_none(list_part_t *list_part);
84 static int is_part_known_none(const partition_t *partition);
85 static void init_structure_none(const disk_t *disk_car,list_part_t *list_part, const int verbose);
86 static const char *get_partition_typename_none_aux(const unsigned int part_type_none);
87 static int set_part_type_none(partition_t *partition, unsigned int part_type);
88 static unsigned int get_part_type_none(const partition_t *partition);
89 static const char *get_partition_typename_none(const partition_t *partition);
90
91 static const struct systypes none_sys_types[] = {
92 {UP_BEOS, "BeFS"},
93 {UP_BTRFS, "btrfs"},
94 {UP_CRAMFS, "CramFS"},
95 {UP_EXT2, "ext2"},
96 {UP_EXT3, "ext3"},
97 {UP_EXT4, "ext4"},
98 /* {UP_EXTENDED, "Extended"}, */
99 {UP_EXFAT, "exFAT"},
100 {UP_FAT12, "FAT12"},
101 {UP_FAT16, "FAT16"},
102 {UP_FAT32, "FAT32"},
103 {UP_FREEBSD, "FreeBSD"},
104 {UP_F2FS, "f2fs"},
105 {UP_GFS2, "GFS2"},
106 {UP_HFS, "HFS"},
107 {UP_HFSP, "HFS+"},
108 {UP_HFSX, "HFSX"},
109 {UP_HPFS, "HPFS"},
110 {UP_ISO, "ISO"},
111 {UP_JFS, "JFS"},
112 {UP_LINSWAP, "Linux SWAP"},
113 {UP_LINSWAP2, "Linux SWAP 2"},
114 {UP_LINSWAP_8K, "Linux SWAP"},
115 {UP_LINSWAP2_8K, "Linux SWAP 2"},
116 {UP_LINSWAP2_8KBE, "Linux SWAP 2"},
117 {UP_LUKS, "Linux LUKS"},
118 {UP_LVM, "Linux LVM"},
119 {UP_LVM2, "Linux LVM2"},
120 {UP_MD, "Linux md 0.9 RAID"},
121 {UP_MD1, "Linux md 1.x RAID"},
122 {UP_NETWARE, "Netware"},
123 {UP_NTFS, "NTFS"},
124 {UP_OPENBSD, "OpenBSD"},
125 {UP_OS2MB, "OS2 Multiboot"},
126 {UP_ReFS, "ReFS"},
127 {UP_RFS, "ReiserFS 3.5"},
128 {UP_RFS2, "ReiserFS 3.6"},
129 {UP_RFS3, "ReiserFS 3.x"},
130 {UP_RFS4, "ReiserFS 4"},
131 {UP_SUN, "Sun"},
132 {UP_SYSV4, "SysV 4"},
133 {UP_UFS, "UFS"},
134 {UP_UFS2, "UFS 2"},
135 {UP_UFS_LE, "UFS - Little Endian"},
136 {UP_UFS2_LE, "UFS 2 - Little Endian"},
137 {UP_UNK, "Unknown"},
138 {UP_VMFS, "VMFS"},
139 {UP_WBFS, "WBFS"},
140 {UP_XFS, "XFS"},
141 {UP_XFS2, "XFS 2"},
142 {UP_XFS3, "XFS 3"},
143 {UP_XFS4, "XFS 4"},
144 {UP_XFS5, "XFS 5"},
145 {UP_ZFS, "ZFS"},
146 { 0,NULL }
147 };
148
149 arch_fnct_t arch_none=
150 {
151 .part_name="None",
152 .part_name_option="partition_none",
153 .msg_part_type=NULL,
154 .read_part=&read_part_none,
155 .write_part=NULL,
156 .init_part_order=&init_part_order_none,
157 .get_geometry_from_mbr=&get_geometry_from_nonembr,
158 .check_part=&check_part_none,
159 .write_MBR_code=NULL,
160 .set_prev_status=&set_next_status_none,
161 .set_next_status=&set_next_status_none,
162 .test_structure=&test_structure_none,
163 .get_part_type=&get_part_type_none,
164 .set_part_type=&set_part_type_none,
165 .init_structure=&init_structure_none,
166 .erase_list_part=NULL,
167 .get_partition_typename=&get_partition_typename_none,
168 .is_part_known=&is_part_known_none
169 };
170
get_part_type_none(const partition_t * partition)171 static unsigned int get_part_type_none(const partition_t *partition)
172 {
173 return partition->upart_type;
174 }
175
get_geometry_from_nonembr(const unsigned char * buffer,const int verbose,CHSgeometry_t * geometry)176 static int get_geometry_from_nonembr(const unsigned char *buffer, const int verbose, CHSgeometry_t *geometry)
177 {
178 {
179 /* Ugly hack to get geometry from FAT and NTFS */
180 const struct fat_boot_sector *fat_header=(const struct fat_boot_sector *)buffer;
181 if(le16(fat_header->marker)==0xAA55)
182 {
183 if(le16(fat_header->secs_track)>0 && le16(fat_header->secs_track)<=63 &&
184 le16(fat_header->heads)>0 && le16(fat_header->heads)<=255 &&
185 fat_sector_size(fat_header)>0 && fat_sector_size(fat_header)%512==0)
186 {
187 geometry->sectors_per_head=le16(fat_header->secs_track);
188 geometry->heads_per_cylinder=le16(fat_header->heads);
189 geometry->bytes_per_sector=fat_sector_size(fat_header);
190 }
191 }
192 }
193 return 0;
194 }
195
read_part_none(disk_t * disk,const int verbose,const int saveheader)196 static list_part_t *read_part_none(disk_t *disk, const int verbose, const int saveheader)
197 {
198 int insert_error=0;
199 unsigned char *buffer_disk;
200 list_part_t *list_part;
201 partition_t *partition;
202 int res=0;
203 partition=partition_new(&arch_none);
204 buffer_disk=(unsigned char *)MALLOC(16*DEFAULT_SECTOR_SIZE);
205 partition->part_size=disk->disk_size;
206 if(recover_MD_from_partition(disk, partition, verbose)==0)
207 res=1;
208 else
209 partition_reset(partition,&arch_none);
210 if(res<=0)
211 {
212 if(disk->pread(disk, buffer_disk, 16 * DEFAULT_SECTOR_SIZE, partition->part_offset) == 16 * DEFAULT_SECTOR_SIZE)
213 res=search_type_2(buffer_disk, disk, partition,verbose,0);
214 }
215 if(res<=0)
216 {
217 res=search_type_1(buffer_disk, disk, partition,verbose,0);
218 }
219 if(res<=0)
220 {
221 res=search_type_0(buffer_disk, disk, partition,verbose,0);
222 }
223 if(res<=0)
224 {
225 res=search_type_8(buffer_disk, disk, partition,verbose,0);
226 }
227 if(res<=0)
228 {
229 if(disk->pread(disk, buffer_disk, 3 * DEFAULT_SECTOR_SIZE, partition->part_offset + 16 * 512) == 3 * DEFAULT_SECTOR_SIZE)
230 res=search_type_16(buffer_disk, disk, partition,verbose,0);
231 }
232 if(res<=0)
233 {
234 if(disk->pread(disk, buffer_disk, 3 * DEFAULT_SECTOR_SIZE, partition->part_offset + 63 * 512) == 3 * DEFAULT_SECTOR_SIZE)
235 res=search_type_64(buffer_disk, disk, partition,verbose,0);
236 }
237 if(res<=0)
238 res=(recover_ISO((const struct iso_primary_descriptor*)(buffer_disk+0x200), partition)==0);
239 if(res<=0)
240 {
241 /* 64k offset */
242 if(disk->pread(disk, buffer_disk, 11 * DEFAULT_SECTOR_SIZE, partition->part_offset + 126 * 512) == 11 * DEFAULT_SECTOR_SIZE)
243 res=search_type_128(buffer_disk, disk, partition,verbose,0);
244 }
245 if(res<=0)
246 {
247 res=search_type_2048(buffer_disk, disk, partition,verbose,0);
248 }
249 if(res<=0)
250 { /* Search FAT32 backup */
251 partition->part_offset = 6*512;
252 res=search_FAT_backup(buffer_disk, disk, partition, verbose, 0);
253 }
254 if(res<=0)
255 { /* Search exFAT backup */
256 partition->part_offset = 12 * disk->sector_size;
257 res=search_exFAT_backup(buffer_disk, disk, partition);
258 }
259 if(res<=0)
260 { /* Search NTFS backup */
261 if(disk->disk_size > disk->sector_size)
262 {
263 partition->part_offset = disk->disk_size - disk->sector_size;
264 res=search_NTFS_backup(buffer_disk, disk, partition, verbose, 0);
265 if(res>0 && partition->part_offset!=0)
266 res=0;
267 }
268 }
269 if(res<=0)
270 {
271 int s_log_block_size;
272 for(s_log_block_size=0; s_log_block_size<=2 && res<=0; s_log_block_size++)
273 {
274 /* sparse superblock feature: The groups chosen are 0, 1 and powers of 3, 5 and 7. */
275 /* Checking group 3 */
276 const uint64_t hd_offset=3*(EXT2_MIN_BLOCK_SIZE<<s_log_block_size)*8*(EXT2_MIN_BLOCK_SIZE<<s_log_block_size)+(s_log_block_size==0?2*DEFAULT_SECTOR_SIZE:0);
277 if(disk->pread(disk, buffer_disk, 1024, hd_offset)==1024)
278 {
279 const struct ext2_super_block *sb=(const struct ext2_super_block*)buffer_disk;
280 partition->part_offset = hd_offset;
281 if(le16(sb->s_block_group_nr)>0 &&
282 le16(sb->s_magic)==EXT2_SUPER_MAGIC &&
283 recover_EXT2(disk, sb, partition, 0, 0)==0)
284 res=1;
285 if(res>0 && partition->part_offset!=0)
286 res=0;
287 }
288 }
289 }
290 free(buffer_disk);
291 if(res<=0)
292 partition_reset(partition,&arch_none);
293 partition->part_offset=0;
294 partition->part_size=disk->disk_size;
295 partition->order=NO_ORDER;
296 partition->status=STATUS_PRIM;
297 screen_buffer_reset();
298 disk->arch->check_part(disk, verbose,partition,saveheader);
299 aff_part_buffer(AFF_PART_ORDER|AFF_PART_STATUS,disk, partition);
300 list_part=insert_new_partition(NULL, partition, 0, &insert_error);
301 if(insert_error>0)
302 free(partition);
303 return list_part;
304 }
305
init_part_order_none(const disk_t * disk_car,list_part_t * list_part)306 static list_part_t *init_part_order_none(const disk_t *disk_car, list_part_t *list_part)
307 {
308 return list_part;
309 }
310
311
set_next_status_none(const disk_t * disk_car,partition_t * partition)312 static void set_next_status_none(const disk_t *disk_car, partition_t *partition)
313 {
314 }
315
test_structure_none(list_part_t * list_part)316 static int test_structure_none(list_part_t *list_part)
317 {
318 return 0;
319 }
320
set_part_type_none(partition_t * partition,unsigned int part_type)321 static int set_part_type_none(partition_t *partition, unsigned int part_type)
322 {
323 partition->upart_type=(upart_type_t)part_type;
324 return 0;
325 }
326
is_part_known_none(const partition_t * partition)327 static int is_part_known_none(const partition_t *partition)
328 {
329 return 1;
330 }
331
init_structure_none(const disk_t * disk_car,list_part_t * list_part,const int verbose)332 static void init_structure_none(const disk_t *disk_car,list_part_t *list_part, const int verbose)
333 {
334 list_part_t *element;
335 for(element=list_part;element!=NULL;element=element->next)
336 {
337 element->part->status=STATUS_PRIM;
338 }
339 }
340
check_part_none(disk_t * disk_car,const int verbose,partition_t * partition,const int saveheader)341 static int check_part_none(disk_t *disk_car,const int verbose,partition_t *partition, const int saveheader)
342 {
343 int ret=0;
344 switch(partition->upart_type)
345 {
346 case UP_BEOS:
347 ret=check_BeFS(disk_car,partition);
348 break;
349 case UP_BTRFS:
350 ret=check_btrfs(disk_car, partition);
351 break;
352 case UP_CRAMFS:
353 ret=check_cramfs(disk_car,partition,verbose);
354 break;
355 case UP_EXT2:
356 case UP_EXT3:
357 case UP_EXT4:
358 ret=check_EXT2(disk_car,partition,verbose);
359 break;
360 case UP_EXTENDED:
361 break;
362 case UP_EXFAT:
363 ret=check_exFAT(disk_car, partition);
364 break;
365 case UP_FAT12:
366 case UP_FAT16:
367 case UP_FAT32:
368 ret=check_FAT(disk_car,partition,verbose);
369 break;
370 case UP_FATX:
371 ret=check_FATX(disk_car, partition);
372 break;
373 case UP_FREEBSD:
374 ret=check_BSD(disk_car,partition,verbose,BSD_MAXPARTITIONS);
375 break;
376 case UP_F2FS:
377 ret=check_f2fs(disk_car, partition);
378 break;
379 case UP_GFS2:
380 ret=check_gfs2(disk_car, partition);
381 break;
382 case UP_HFS:
383 ret=check_HFS(disk_car,partition,verbose);
384 break;
385 case UP_HFSP:
386 case UP_HFSX:
387 ret=check_HFSP(disk_car,partition,verbose);
388 break;
389 case UP_HPFS:
390 ret=check_HPFS(disk_car,partition,verbose);
391 break;
392 case UP_ISO:
393 ret=check_ISO(disk_car, partition);
394 break;
395 case UP_JFS:
396 ret=check_JFS(disk_car, partition);
397 break;
398 case UP_LINSWAP:
399 case UP_LINSWAP2:
400 case UP_LINSWAP_8K:
401 case UP_LINSWAP2_8K:
402 case UP_LINSWAP2_8KBE:
403 ret=check_Linux_SWAP(disk_car, partition);
404 break;
405 case UP_LUKS:
406 ret=check_LUKS(disk_car, partition);
407 break;
408 case UP_LVM:
409 ret=check_LVM(disk_car,partition,verbose);
410 break;
411 case UP_LVM2:
412 ret=check_LVM2(disk_car,partition,verbose);
413 break;
414 case UP_NETWARE:
415 ret=check_netware(disk_car, partition);
416 break;
417 case UP_NTFS:
418 ret=check_NTFS(disk_car,partition,verbose,0);
419 if(ret!=0)
420 { screen_buffer_add("Invalid NTFS boot\n"); }
421 break;
422 case UP_OPENBSD:
423 ret=check_BSD(disk_car,partition,verbose,OPENBSD_MAXPARTITIONS);
424 break;
425 case UP_OS2MB:
426 ret=check_OS2MB(disk_car,partition,verbose);
427 break;
428 case UP_MD:
429 case UP_MD1:
430 ret=check_MD(disk_car,partition,verbose);
431 if(ret!=0)
432 { screen_buffer_add("Invalid RAID superblock\n"); }
433 break;
434 case UP_ReFS:
435 ret=check_ReFS(disk_car, partition);
436 break;
437 case UP_RFS:
438 case UP_RFS2:
439 case UP_RFS3:
440 case UP_RFS4:
441 ret=check_rfs(disk_car,partition,verbose);
442 break;
443 case UP_SUN:
444 ret=check_sun_i386(disk_car,partition,verbose);
445 break;
446 case UP_SYSV4:
447 ret=check_sysv(disk_car,partition,verbose);
448 break;
449 case UP_UFS:
450 case UP_UFS2:
451 case UP_UFS_LE:
452 case UP_UFS2_LE:
453 ret=check_ufs(disk_car,partition,verbose);
454 break;
455 case UP_VMFS:
456 ret=check_VMFS(disk_car, partition);
457 break;
458 case UP_WBFS:
459 ret=check_WBFS(disk_car, partition);
460 break;
461 case UP_XFS:
462 case UP_XFS2:
463 case UP_XFS3:
464 case UP_XFS4:
465 case UP_XFS5:
466 ret=check_xfs(disk_car,partition,verbose);
467 break;
468 case UP_ZFS:
469 ret=check_ZFS(disk_car, partition);
470 break;
471 case UP_UNK:
472 break;
473 }
474 return ret;
475 }
476
get_partition_typename_none_aux(const unsigned int part_type_none)477 static const char *get_partition_typename_none_aux(const unsigned int part_type_none)
478 {
479 int i;
480 for (i=0; none_sys_types[i].name!=NULL; i++)
481 if (none_sys_types[i].part_type == part_type_none)
482 return none_sys_types[i].name;
483 return NULL;
484 }
485
get_partition_typename_none(const partition_t * partition)486 static const char *get_partition_typename_none(const partition_t *partition)
487 {
488 return get_partition_typename_none_aux(partition->upart_type);
489 }
490