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