Compare commits
43 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
bdfd4c4a37 | |||
dfc6de9f79 | |||
7234425502 | |||
4e5a54c2f9 | |||
028f9275d3 | |||
cace41ec16 | |||
e599a575dc | |||
78b0a7b111 | |||
a7152f5794 | |||
2a64d89e6e | |||
31088d9acc | |||
91490d5f34 | |||
661b68ce8c | |||
16bde11076 | |||
36c8800ff3 | |||
860a91dd2f | |||
280108d2d5 | |||
1e40ed3fab | |||
e19a338a09 | |||
c6e4035918 | |||
18ab6019bc | |||
6282bbc0bc | |||
d7737e3ed5 | |||
fb8697081b | |||
0e7300b1a8 | |||
94e4bfb42b | |||
86f6ffc9c9 | |||
5600f3d726 | |||
e66b9bfe0c | |||
094b3f7546 | |||
5c1c5cd964 | |||
215280448f | |||
3043b5f660 | |||
afb10aac3b | |||
76181d0aa3 | |||
8ec75eea6a | |||
01020ef544 | |||
2961bdef9f | |||
ed209e0b6e | |||
dc6cd946ba | |||
c51efce8d1 | |||
8bf32d8d14 | |||
561e2a6aaa |
@ -1,7 +1,9 @@
|
||||
Vreixo Formoso <metalpain2002@yahoo.es>,
|
||||
Mario Danic <mario.danic@gmail.com>,
|
||||
Vladimir Serbinenko <phcoder@gmail.com>
|
||||
Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (C) 2007-2015 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
||||
Copyright (C) 2007-2016
|
||||
Vreixo Formoso, Mario Danic, Vladimir Serbinenko, Thomas Schmitt
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
19
ChangeLog
19
ChangeLog
@ -1,3 +1,22 @@
|
||||
libisofs-1.4.8.tar.gz Tue Sep 12 2017
|
||||
===============================================================================
|
||||
* Bug fix: iso_read_opts_set_no_rockridge() did not prevent reading of root
|
||||
SUSP.
|
||||
* Bug fix: Non-SUSP data in System Use Area prevented image loading if
|
||||
Rock Ridge was enabled. Thanks to Jonathan Dowland.
|
||||
* Bug fix: Protective MBR for GPT could emerge with boot flag set.
|
||||
* Bug fix: Appended partitions of size >= 4 GiB led to abort with error message
|
||||
"FATAL : ISO overwrite". Thanks to Sven Haardiek.
|
||||
* Bug fix: Bit 15 of iso_write_opts_set_system_area did not work with generic
|
||||
MBR.
|
||||
* Bug fix: Keeping and patching of loaded boot images failed.
|
||||
Regression by version 1.4.4.
|
||||
* Bug fix: Program crashes by intentionally wrong ISO image input.
|
||||
Found by American Fuzzy Lop and Jakub Wilk.
|
||||
Debian bug reports: 872372, 872475, 872545, 872590, 872761.
|
||||
* New API calls el_torito_set_full_load(), el_torito_get_full_load().
|
||||
* New API call iso_write_opts_set_iso_mbr_part_type().
|
||||
|
||||
|
||||
libisofs-1.4.6.tar.gz Fri Sep 16 2016
|
||||
===============================================================================
|
||||
|
12
configure.ac
12
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([libisofs], [1.4.6], [http://libburnia-project.org])
|
||||
AC_INIT([libisofs], [1.4.8], [http://libburnia-project.org])
|
||||
AC_PREREQ([2.50])
|
||||
dnl AC_CONFIG_HEADER([config.h])
|
||||
|
||||
@ -41,7 +41,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||
dnl
|
||||
LIBISOFS_MAJOR_VERSION=1
|
||||
LIBISOFS_MINOR_VERSION=4
|
||||
LIBISOFS_MICRO_VERSION=6
|
||||
LIBISOFS_MICRO_VERSION=8
|
||||
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
||||
|
||||
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
||||
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
|
||||
|
||||
dnl Libtool versioning
|
||||
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
||||
# 2016.07.01 development jump has not yet happened
|
||||
# SONAME = 88 - 82 = 6 . Library name = libisofs.6.82.0
|
||||
LT_CURRENT=88
|
||||
LT_AGE=82
|
||||
# 2017.09.12 development jump has not yet happened
|
||||
# SONAME = 90 - 84 = 6 . Library name = libisofs.6.84.0
|
||||
LT_CURRENT=90
|
||||
LT_AGE=84
|
||||
LT_REVISION=0
|
||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||
|
||||
|
@ -301,28 +301,44 @@ Byte Range | Value | Meaning
|
||||
|
||||
Sources:
|
||||
http://en.wikipedia.org/wiki/Master_boot_record
|
||||
https://en.wikipedia.org/wiki/INT_13H
|
||||
Mailing list conversations with H. Peter Anvin and Vladimir Serbinenko.
|
||||
Mail conversations with Natalia Portillo.
|
||||
|
||||
|
||||
The candidates for MBR booting will normally use El Torito rather than MBR
|
||||
if the ISO image is presented on CD, DVD, or BD media.
|
||||
The eventual MBR comes into effect if the image is on a media that is
|
||||
interpreted by the BIOS as some kind of hard disk. Usually real hard disks,
|
||||
floppy disks, USB sticks, memory cards.
|
||||
The MBR comes into effect if the image is on a media that is interpreted by
|
||||
the BIOS as some kind of hard disk. Usually real hard disks, floppy disks,
|
||||
USB sticks, memory cards.
|
||||
|
||||
An important part of an MBR is the DOS style partition table. It describes up
|
||||
to four primary partitions. There are two formats used for block address:
|
||||
Cylinder/Head/Sector (C/H/S) and Logical Block Address (LBA). Both are based
|
||||
on units of 512 bytes. So MBR_LBA = ISO_LBA * 4.
|
||||
|
||||
Contemporary x86 BIOS normally supports LBA addressing directly.
|
||||
If INT 0x13 AH 0x41 returns with CX bit0 set, then INT 0x13 AH 0x42 may be used
|
||||
for reading. (Sometimes even if the bit is not set to indicate the capability.)
|
||||
|
||||
For C/H/S, the sector address is broken up into whole cylinders, remaining
|
||||
heads, and remaining sectors + 1. The nomenclature seems to stem from antique
|
||||
drum storage.
|
||||
There are two parameters, sectors_per_head and heads_per_cylinder which are not
|
||||
stored in the MBR. So it is more or less arbitray how to convert a LBA into
|
||||
a C/H/S address and vice versa. For maximum range of C/H/S addresses one
|
||||
may use sectors_per_head = 63 , heads_per_cylinder = 255.
|
||||
stored in the MBR. So at ISO production time it is more or less arbitray how
|
||||
to convert a LBA into a C/H/S address and vice versa.
|
||||
At boot time the x86 BIOS decides about the two parameters. The boot loader may
|
||||
inquire these values by INT 0x13 AH 0x08 and use them to convert LBA to C/H/S
|
||||
for the read operation INT 0x13 AH 0x02. So the C/H/S values in an ISO's
|
||||
partition table are quite fictional and of few impact on boot loaders.
|
||||
|
||||
More important seems to align partition ends to a consistent cylinder size,
|
||||
because some partition editors deduce their idea of disk geometry from there
|
||||
and raise protest if they deem it inconsistent.
|
||||
For maximum range of C/H/S addresses one may use sectors_per_head = 63 ,
|
||||
heads_per_cylinder = 255. But that is not divisible by 4 and imposes alignment
|
||||
problems with ISO 9660 filesystems. So (32,64) for images up to 1 GiB
|
||||
or (63,252) for larger images are better.
|
||||
|
||||
Words are composed little-endian style.
|
||||
|
||||
@ -331,8 +347,9 @@ Byte Range | Value | Meaning
|
||||
0 - 439 | = opaque = | Code Area filled with bytes for some boot system,
|
||||
| | typically machine code.
|
||||
| |
|
||||
440 - 443 | disk_sgntr | Disc signature, an individual disk id of obscure
|
||||
| | usability.
|
||||
440 - 443 | disk_sgntr | Disc signature: An individual disk id. Some software
|
||||
| | might use it to recognize the same storage medium
|
||||
| | at different device addresses.
|
||||
| | (The Code Area might extend up to this field.)
|
||||
| |
|
||||
444 - 445 | 0 | "usually nulls"
|
||||
@ -340,8 +357,11 @@ Byte Range | Value | Meaning
|
||||
| |
|
||||
446 - 461 | ========== | Partition Table Entry for partition 1
|
||||
| |
|
||||
446 - 446 | status | Governs bootability:
|
||||
| | 0x80 = bootable/active , 0x00 non-bootable/inactive
|
||||
446 - 446 | status | For some generic MBRs this marks the one partition
|
||||
| | from which the MBR should load and run more code.
|
||||
| | 0x80 = bootflag/active , 0x00 = noboot/inactive
|
||||
| | Some BIOSes ignore MBRs with no bootflag in any of
|
||||
| | their partition table entries.
|
||||
| |
|
||||
447 - 449 | ========== | C/H/S address of partition start
|
||||
447 - 447 | start_head | Heads part of start address.
|
||||
@ -404,6 +424,8 @@ Sources:
|
||||
http://www.informit.com/articles/article.aspx?p=376123&seqNum=3
|
||||
syslinux-4.05/utils/isohybrid.c
|
||||
Mail conversations with Vladimir Serbinenko.
|
||||
Mail conversations with Natalia Portillo of DiskImageChef,
|
||||
who quoted "Inside Macintosh" Volumes IV and V.
|
||||
|
||||
|
||||
APM has an adjustable block size. Because the ISO images shall always work
|
||||
@ -412,11 +434,19 @@ additional GPT, only block size 2048 is considered here.
|
||||
The role of APM in the boot process is to guide the firmware to a
|
||||
HFS+ filesystem.
|
||||
|
||||
Block0 of an APM begins at byte 0 of the medium. Thus it collides with MBR and
|
||||
other boot sector formats. By lucky coincidence it is possible to compose
|
||||
a mock-up of a Block0 which is acceptable to firmware which expects APM,
|
||||
and is also harmless x86 machine code with no negative side effects.
|
||||
So it is possible to combine APM with an especially prepared MBR.
|
||||
Block0 (aka Driver Descriptor Map) of an APM begins at byte 0 of the medium.
|
||||
Thus it collides with MBR and other boot sector formats. By lucky coincidence
|
||||
it is possible to compose a mock-up of a Block0 which is acceptable to firmware
|
||||
which expects APM, and is also harmless x86 machine code with no negative
|
||||
side effects. So it is possible to combine APM with an especially prepared MBR.
|
||||
|
||||
Block0 is optional. But in the context of bootable hybrid ISOs it is not only
|
||||
needed to announce block size 2048, but also it is much better suited for
|
||||
staging as harmless x86 machine code than is an APM partition entry.
|
||||
|
||||
Usually there is no Device Partition Map block (signature "TS"), although it
|
||||
is demanded by the book "Inside Macintosh". It would sit where GPT has its
|
||||
header block. So DPM is not described here.
|
||||
|
||||
The layout of a Block0 of an APM is:
|
||||
|
||||
@ -427,13 +457,17 @@ Byte Range | Value | Meaning (all numbers are stored big endian)
|
||||
4 - 7 | block_count| Number of blocks covered by APM
|
||||
| | Often some x86-harmless dummy. E.g. 0x9090 = 37008
|
||||
| | or 0xeb02ffff = 3,942,842,367
|
||||
8 - 9 | dev_type | obscure: "device type"
|
||||
10 - 11 | dev_id | obscure: "device id"
|
||||
12 - 15 | drv_data | obscure: "driver data"
|
||||
16 - 17 | drv_count | obscure: "driver descriptor count"
|
||||
18 - 81 | drv_map | obscure: "driver descriptor table"
|
||||
| | with 8 entries of 16 bytes each
|
||||
82 - 511 | reserved |
|
||||
8 - 9 | dev_type | Device type: The id of the Mac driver which is in
|
||||
| | charge of the storage device.
|
||||
10 - 11 | dev_id | Device id: Address in an i/o bus system.
|
||||
12 - 15 | drv_data | Driver data: Not used.
|
||||
16 - 17 | drv_count | Driver count: Count of entries in drv_map.
|
||||
18 - 505 | drv_map | Driver descriptor table:
|
||||
| | Up to 61 entries of 8 bytes each.
|
||||
| | They contain the 32 bit 512-byte LBA of the driver's
|
||||
| | storage location, its 16 bit size in 512-byte blocks,
|
||||
| | and value 0x0001.
|
||||
506 - 511 | reserved |
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
The SYSLINUX program isohybrid.c overwrites the first 32 bytes of this
|
||||
@ -463,9 +497,12 @@ Byte Range | Value | Meaning (all numbers are stored big endian)
|
||||
84 - 87 | lb_count | Logical block count (same as block_count)
|
||||
88 - 91 | flags | Status flags
|
||||
| | bit0= entry is valid
|
||||
| | bit1= entry is allocated
|
||||
| | bit1= partition is allocated
|
||||
| | bit2= partition is in use
|
||||
| | bit3= partition contains valid boot information
|
||||
| | bit4= partition is readable
|
||||
| | bit5= partition is writable
|
||||
| | bit7= boot code is position independent
|
||||
| | bit30= automatic mount (legacy Mac)
|
||||
92 - 95 | boot_block | Logical start block number of boot code = 0
|
||||
96 - 99 | boot_bytes | Number of bytes in boot code = 0
|
||||
@ -649,6 +686,7 @@ Sources:
|
||||
There are traces in the web which relate this to specs by
|
||||
MIPS Computer Systems, Inc. , 1985
|
||||
Silicon Graphics Computer Systems, Inc. , 2000
|
||||
Mail conversations with Natalia Portillo.
|
||||
|
||||
|
||||
The first 512 bytes of the media constitute the Volume Header.
|
||||
@ -659,7 +697,11 @@ Byte Range | Value | Meaning
|
||||
0 - 3 | 0x0be5a941 | Magic number
|
||||
4 - 5 | 0 | Root partition number
|
||||
6 - 7 | 0 | Swap partition number
|
||||
8 - 23 | 0 | Name of file to boot (unclear what this means)
|
||||
8 - 23 | 0 | One of the boot_name items from the Volume Directory
|
||||
| | may be put here to choose for booting the entry with
|
||||
| | that name.
|
||||
| | (Obviously it may be empty if only one non-zero entry
|
||||
| | exists in the Volume Directory.)
|
||||
| |
|
||||
24 - 71 | ========== | Device Parameters
|
||||
| |
|
||||
|
@ -4,7 +4,7 @@
|
||||
Directory of Namespace "isofs."
|
||||
|
||||
by Thomas Schmitt - mailto:scdbackup@gmx.net
|
||||
Libburnia project - mailto:libburn-hackers@pykix.org
|
||||
Libburnia project - mailto:bug-xorriso@gnu.org
|
||||
|
||||
|
||||
The following names are defined for AAIP namespace "isofs." as mentioned in
|
||||
@ -227,7 +227,7 @@ This text is under
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||
It shall only be modified in sync with libisofs and other software which
|
||||
makes use of AAIP. Please mail change requests to mailing list
|
||||
<libburn-hackers@pykix.org> or to the copyright holder in private.
|
||||
<bug-xorriso@gnu.org> or to the copyright holder in private.
|
||||
Only if you cannot reach the copyright holder for at least one month it is
|
||||
permissible to modify this text under the same license as the affected
|
||||
copy of libisofs.
|
||||
|
234
libisofs/changelog.txt
Normal file
234
libisofs/changelog.txt
Normal file
@ -0,0 +1,234 @@
|
||||
------------------------------------------------------------------------------
|
||||
libburnia-project.org / dev.lovelyhq.com libisofs
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Changelog
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
13 Nov 2016 [8bf32d8] [1340]
|
||||
doc/susp_aaip_isofs_names.txt
|
||||
Prepared some of the documentation for move to dev.lovelyhq.com
|
||||
|
||||
13 Nov 2016 [c51efce] [1341]
|
||||
libisofs/fs_image.c
|
||||
Bug fix: iso_read_opts_set_no_rockridge() did not prevent reading of root SUSP
|
||||
|
||||
13 Nov 2016 [dc6cd94] [1342]
|
||||
libisofs/libisofs.h
|
||||
libisofs/eltorito.c
|
||||
libisofs/libisofs.ver
|
||||
New API calls el_torito_set_full_load(), el_torito_get_full_load()
|
||||
|
||||
13 Nov 2016 [ed209e0] [1343]
|
||||
COPYRIGHT
|
||||
Mentioned Vladimir Serbinenko in libisofs copyright list
|
||||
|
||||
13 Nov 2016 [2961bde] [1344]
|
||||
ChangeLog
|
||||
+ libisofs/changelog.txt
|
||||
Updated change log
|
||||
|
||||
23 Nov 2016 [01020ef] [1345]
|
||||
libisofs/eltorito.h
|
||||
Committed missing part of rev dc6cd94/1342
|
||||
|
||||
23 Nov 2016 [8ec75ee] [1346]
|
||||
libisofs/fs_image.c
|
||||
libisofs/rockridge.h
|
||||
libisofs/rockridge_read.c
|
||||
Bug fix: Non-SUSP data in System Use Area prevented image loading if Rock Ridge was enabled. Thanks to Jonathan Dowland.
|
||||
|
||||
25 Dec 2016 [76181d0] [1347]
|
||||
libisofs/ecma119.c
|
||||
Restricted volume size of PVD with non-zero partition offset to filesystem
|
||||
size even if the first PVD claims the whole output size
|
||||
|
||||
25 Dec 2016 [afb10aa] [1348]
|
||||
libisofs/eltorito.c
|
||||
Claiming full output size in first PVD if partition offset is non-zero
|
||||
|
||||
25 Dec 2016 [3043b5f] [1349]
|
||||
libisofs/fs_image.c
|
||||
Enabled recognition of partition offset of grub-mkrescue-sed.sh mode "gpt_appended"
|
||||
|
||||
03 Jan 2017 [2152804] [1350]
|
||||
libisofs/system_area.c
|
||||
Bug fix: Protective MBR for GPT could emerge with boot flag set.
|
||||
|
||||
24 Jan 2014 [5c1c5cd] [1351]
|
||||
libisofs/system_area.c
|
||||
Bug fix: Appended partitions of size >= 4 GiB led to abort with error message
|
||||
"FATAL : ISO overwrite". Thanks to Sven Haardiek.
|
||||
|
||||
24 Jan 2014 [094b3f7] [1352]
|
||||
libisofs/system_area.c
|
||||
Updated copyright year in system_area.c
|
||||
|
||||
27 Feb 2014 [e66b9bf] [1353]
|
||||
libisofs/libisofs.h
|
||||
libisofs/ecma119.h
|
||||
libisofs/ecma119.c
|
||||
libisofs/system_area.c
|
||||
libisofs/libisofs.ver
|
||||
New API call iso_write_opts_set_iso_mbr_part_type()
|
||||
|
||||
27 Feb 2014 [5600f3d] [1354]
|
||||
libisofs/system_area.c
|
||||
When deciding boot flag, consider MBR partition slot empty only if entirely 0
|
||||
|
||||
19 Mar 2017 [86f6ffc] [1355]
|
||||
libisofs/system_area.c
|
||||
Let iso_mbr_part_type 0xee override ban on 0xee without GPT
|
||||
|
||||
09 Apr 2017 [94e4bfb] [1356]
|
||||
libisofs/fs_image.c
|
||||
Adapted recognizing of partition offset to the changes of rev afb10aa / 1348
|
||||
|
||||
10 Apr 2017 [0e7300b] [1357]
|
||||
doc/boot_sectors.txt
|
||||
Clarified meaning of MBR partition boot flag
|
||||
|
||||
25 Apr 2017 [fb86970] [1358]
|
||||
libisofs/system_area.c
|
||||
Reacted on harmless compiler warning about uninitialized variable.
|
||||
|
||||
03 Jun 2017 [d7737e3] []
|
||||
libisofs/fs_image.c
|
||||
Removed ban on reading El Torito platform ids other than 0 and 0xef
|
||||
|
||||
29 Jun 2017 [6282bbc]
|
||||
libisofs/system_area.c
|
||||
Bug fix: Bit 15 of iso_write_opts_set_system_area did not work with generic MBR
|
||||
|
||||
01 Jul 2017 [18ab601]
|
||||
libisofs/eltorito.c
|
||||
libisofs/system_area.c
|
||||
Let ISO size cover appended partitions if --protective-msdos-label or nonzero -partition_offset is given
|
||||
|
||||
13 Aug 2017 [c6e4035]
|
||||
doc/boot_sectors.txt
|
||||
Added boot sector knowledge gained from Natalia Portillo
|
||||
|
||||
13 Aug 2017 [e19a338]
|
||||
doc/boot_sectors.txt
|
||||
Re-added two empty lines which were lost by previous commit
|
||||
|
||||
14 Aug 2014 [1e40ed3]
|
||||
libisofs/fs_image.c
|
||||
Bug fix: Keeping and patching of loaded boot images failed. Regression by version 1.4.4.
|
||||
|
||||
14 Aug 2017 [280108d]
|
||||
ChangeLog
|
||||
libisofs/changelog.txt
|
||||
Updated change log
|
||||
|
||||
17 Aug 2017 [860a91d]
|
||||
libisofs/libisofs.h
|
||||
libisofs/fs_image.c
|
||||
libisofs/messages.c
|
||||
Preventing NULL dereference if root directory bears a RRIP RE entry
|
||||
|
||||
18 Aug 2017 [36c8800]
|
||||
libisofs/rockridge_read.c
|
||||
Preventing buffer underread with empty RRIP SL component.
|
||||
Debian bug 872475. Thanks Jakub Wilk and American Fuzzy Lop.
|
||||
|
||||
18 Aug 2017 [16bde11]
|
||||
libisofs/fs_image.c
|
||||
Preventing memory leak caused by RRIP SL entry without PX entry that marks
|
||||
the file as symbolic link
|
||||
|
||||
18 Aug 2017 [661b68c]
|
||||
libisofs/rockridge_read.c
|
||||
Preventing buffer overflow with AAIP AL entry of insufficient size.
|
||||
Debian bug 872545. Thanks Jakub Wilk and American Fuzzy Lop.
|
||||
|
||||
19 Aug 2017 [91490d5]
|
||||
libisofs/libisofs.h
|
||||
libisofs/messages.c
|
||||
libisofs/rockridge_read.c
|
||||
Preventing use of zero sized SUSP CE entry which causes SIGSEGV.
|
||||
Debian bug 872590. Thanks Jakub Wilk and American Fuzzy Lop.
|
||||
|
||||
19 Aug 2017 [31088d9]
|
||||
libisofs/rockridge_read.c
|
||||
Avoid to read blocks from start of CE area which do not belong to the given file
|
||||
|
||||
19 Aug 2017 [2a64d89]
|
||||
libisofs/libisofs.h
|
||||
libisofs/rockridge.h
|
||||
libisofs/fs_image.c
|
||||
libisofs/rockridge_read.c
|
||||
libisofs/messages.c
|
||||
Refuse to read CE data blocks from after the end of ISO filesystem
|
||||
|
||||
21 Aug 2017 [a7152f5]
|
||||
libisofs/fs_image.c
|
||||
Correcting previous commit for supporting multi-session
|
||||
|
||||
21 Aug 2017 [78b0a7b]
|
||||
libisofs/fs_image.c
|
||||
Disallowed RRIP CL chaining in order to break any endless loops.
|
||||
Debian bug 872761. Thanks Jakub Wilk and American Fuzzy Lop.
|
||||
|
||||
21 Aug 2017 [e599a57]
|
||||
libisofs/fs_image.c
|
||||
Closed a memory leak about RRIP CL following
|
||||
|
||||
24 Aug 2017 [cace41e]
|
||||
libisofs/ecma119.h
|
||||
libisofs/ecma119.c
|
||||
libisofs/system_area.c
|
||||
Enabled partition intervals with source "imported_iso" with ISO growing
|
||||
|
||||
26 Aug 2017 [028f927]
|
||||
libisofs/libisofs.h
|
||||
libisofs/ecma119.c
|
||||
libisofs/system_area.c
|
||||
libisofs/messages.c
|
||||
Throw error if imported_iso interval would be overwritten by multi-session
|
||||
|
||||
09 Sep 2017 [4e5a54c]
|
||||
libisofs/fs_image.c
|
||||
Swapped at recognition time the precendence of MBR properties "isohybrid"
|
||||
and "protective-msdos-label"
|
||||
|
||||
12 Sep 2017 [7234425]
|
||||
ChangeLog
|
||||
Updated change log
|
||||
|
||||
[]
|
||||
configure.ac
|
||||
libisofs/libisofs.h
|
||||
Version leap to 1.4.8.
|
||||
|
||||
[]
|
||||
libisofs/changelog.txt
|
||||
Updated change log
|
||||
|
||||
------------------------------------ release - libisofs-1.4.8 - 12 Sep 2017
|
||||
* Bug fix: iso_read_opts_set_no_rockridge() did not prevent reading of root SUSP
|
||||
* Bug fix: Non-SUSP data in System Use Area prevented image loading if
|
||||
Rock Ridge was enabled. Thanks to Jonathan Dowland.
|
||||
* Bug fix: Protective MBR for GPT could emerge with boot flag set.
|
||||
* Bug fix: Appended partitions of size >= 4 GiB led to abort with error message
|
||||
"FATAL : ISO overwrite". Thanks to Sven Haardiek.
|
||||
* Bug fix: Bit 15 of iso_write_opts_set_system_area did not work with
|
||||
generic MBR.
|
||||
* Bug fix: Keeping and patching of loaded boot images failed.
|
||||
Regression by version 1.4.4.
|
||||
* Bug fix: Program crashes by intentionally wrong ISO image input.
|
||||
Found by American Fuzzy Lop and Jakub Wilk.
|
||||
Debian bug reports: 872372, 872475, 872545, 872590, 872761.
|
||||
* New API calls el_torito_set_full_load(), el_torito_get_full_load().
|
||||
* New API call iso_write_opts_set_iso_mbr_part_type().
|
||||
|
||||
|
||||
[]
|
||||
ChangeLog
|
||||
libisofs/changelog.txt
|
||||
Updated change log
|
||||
|
||||
------------------------------------ release - libisofs-1.5.0 -
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 - 2016 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2017 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -1417,6 +1417,7 @@ int write_head_part2(Ecma119Image *target, int *write_count, int flag)
|
||||
target->partiton_offset from any LBA pointer.
|
||||
*/
|
||||
target->eff_partition_offset = target->opts->partition_offset;
|
||||
target->pvd_size_is_total_size = 0;
|
||||
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||
writer = target->writers[i];
|
||||
/* Not all writers have an entry in the partion volume descriptor set.
|
||||
@ -1497,9 +1498,6 @@ static int finish_libjte(Ecma119Image *target)
|
||||
}
|
||||
|
||||
|
||||
/* >>> need opportunity to just mark a partition in the older sessions
|
||||
*/
|
||||
|
||||
|
||||
struct iso_interval_zeroizer {
|
||||
int z_type; /* 0= $zero_start"-"$zero_end ,
|
||||
@ -2000,6 +1998,50 @@ process_pending:;
|
||||
}
|
||||
|
||||
|
||||
/* Tells whether ivr is a reader from imported_iso in a multi-session
|
||||
add-on situation, and thus to be kept in place.
|
||||
*/
|
||||
int iso_interval_reader_keep(Ecma119Image *target,
|
||||
struct iso_interval_reader *ivr,
|
||||
int flag)
|
||||
{
|
||||
/* Source must be "imported_iso" */
|
||||
if (!(ivr->flags & 1))
|
||||
return 0;
|
||||
|
||||
/* It must not be a new ISO */
|
||||
if (!target->opts->appendable)
|
||||
return 0;
|
||||
|
||||
/* --- From here on return either 1 or <0 --- */
|
||||
|
||||
/* multi-session write offset must be larger than interval end */
|
||||
if (target->opts->ms_block <= ivr->end_byte / BLOCK_SIZE)
|
||||
return ISO_MULTI_OVER_IMPORTED;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int iso_interval_reader_start_size(Ecma119Image *t, char *path,
|
||||
off_t *start_byte, off_t *byte_count,
|
||||
int flag)
|
||||
{
|
||||
struct iso_interval_reader *ivr;
|
||||
int keep, ret;
|
||||
|
||||
ret = iso_interval_reader_new(t->image, path, &ivr, byte_count, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*start_byte = ivr->start_byte;
|
||||
keep = iso_interval_reader_keep(t, ivr, 0);
|
||||
if (keep < 0)
|
||||
return(keep);
|
||||
iso_interval_reader_destroy(&ivr, 0);
|
||||
return ISO_SUCCESS + (keep > 0);
|
||||
}
|
||||
|
||||
|
||||
int iso_write_partition_file(Ecma119Image *target, char *path,
|
||||
uint32_t prepad, uint32_t blocks, int flag)
|
||||
{
|
||||
@ -2025,6 +2067,14 @@ int iso_write_partition_file(Ecma119Image *target, char *path,
|
||||
&ivr, &byte_count, 0);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
ret = iso_interval_reader_keep(target, ivr, 0);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
if (ret > 0) {
|
||||
/* From imported_iso and for add-on session. Leave it in place. */
|
||||
ret = ISO_SUCCESS;
|
||||
goto ex;
|
||||
}
|
||||
for (i = 0; i < blocks; i++) {
|
||||
ret = iso_interval_reader_read(ivr, buf, &buf_fill, 0);
|
||||
if (ret < 0)
|
||||
@ -3482,6 +3532,7 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
||||
wopts->appended_as_gpt = 0;
|
||||
wopts->appended_as_apm = 0;
|
||||
wopts->part_like_isohybrid = 0;
|
||||
wopts->iso_mbr_part_type = -1;
|
||||
wopts->ascii_disc_label[0] = 0;
|
||||
wopts->will_cancel = 0;
|
||||
wopts->allow_dir_id_ext = 0;
|
||||
@ -4217,6 +4268,14 @@ int iso_write_opts_set_part_like_isohybrid(IsoWriteOpts *opts, int alike)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_iso_mbr_part_type(IsoWriteOpts *opts, int part_type)
|
||||
{
|
||||
if (part_type < -1 || part_type > 255)
|
||||
part_type = -1;
|
||||
opts->iso_mbr_part_type = part_type;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label)
|
||||
{
|
||||
strncpy(opts->ascii_disc_label, label, ISO_DISC_LABEL_SIZE - 1);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2015 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2017 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -496,6 +496,14 @@ struct iso_write_opts {
|
||||
*/
|
||||
int part_like_isohybrid;
|
||||
|
||||
/* The type to use for the mountable ISO partition if there is any and if
|
||||
the type is not mandatorily determined for particular circumstances like
|
||||
compliant GPT, CHRP, or PReP.
|
||||
-1 = use the default value (e.g. 0xcd, 0x83, 0x17)
|
||||
0x00 to 0xff = value to use if possible
|
||||
*/
|
||||
int iso_mbr_part_type;
|
||||
|
||||
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
|
||||
*/
|
||||
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
|
||||
@ -1024,5 +1032,18 @@ int iso_write_partition_file(Ecma119Image *target, char *path,
|
||||
|
||||
void issue_ucs2_warning_summary(size_t failures);
|
||||
|
||||
/* Tells whether ivr is a reader from imported_iso in a multi-session
|
||||
add-on situation, and thus to be kept in place.
|
||||
*/
|
||||
int iso_interval_reader_keep(Ecma119Image *target,
|
||||
struct iso_interval_reader *ivr,
|
||||
int flag);
|
||||
|
||||
/* @return: ISO_SUCCESS = ok, ISO_SUCCESS + 1 = keep , < 0 = error */
|
||||
int iso_interval_reader_start_size(Ecma119Image *t, char *path,
|
||||
off_t *start_byte, off_t *byte_count,
|
||||
int flag);
|
||||
|
||||
|
||||
|
||||
#endif /*LIBISO_ECMA119_H_*/
|
||||
|
@ -113,9 +113,24 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors)
|
||||
/* API */
|
||||
int el_torito_get_load_size(ElToritoBootImage *bootimg)
|
||||
{
|
||||
return (int) bootimg->load_size;
|
||||
return (int) bootimg->load_size;
|
||||
}
|
||||
|
||||
/* API */
|
||||
void el_torito_set_full_load(ElToritoBootImage *bootimg, int mode)
|
||||
{
|
||||
if (bootimg->type != 0)
|
||||
return;
|
||||
bootimg->load_size_full= !!mode;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int el_torito_get_full_load(ElToritoBootImage *bootimg)
|
||||
{
|
||||
return bootimg->load_size_full;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Marks the specified boot image as not bootable
|
||||
*/
|
||||
@ -513,6 +528,7 @@ int create_image(IsoImage *image, const char *image_path,
|
||||
boot->partition_type = partition_type;
|
||||
boot->load_seg = 0;
|
||||
boot->load_size = load_sectors;
|
||||
boot->load_size_full = 0;
|
||||
boot->platform_id = 0; /* 80x86 */
|
||||
memset(boot->id_string, 0, sizeof(boot->id_string));
|
||||
memset(boot->selection_crit, 0, sizeof(boot->selection_crit));
|
||||
@ -887,6 +903,32 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
|
||||
sizeof(e->id_string));
|
||||
}
|
||||
|
||||
static int
|
||||
write_section_load_size(struct el_torito_boot_image *img,
|
||||
struct el_torito_section_entry *se,
|
||||
uint16_t load_size, off_t full_byte_size, int flag)
|
||||
{
|
||||
uint16_t size;
|
||||
off_t blocks;
|
||||
|
||||
size= load_size;
|
||||
if(img->type == 0 && img->load_size_full) {
|
||||
blocks= ((full_byte_size + 2047) / 2048) * 4;
|
||||
if (blocks > 65535) {
|
||||
if (img->platform_id == 0xef)
|
||||
size= 0;
|
||||
else
|
||||
size= 65535;
|
||||
} else if(blocks <= 0) {
|
||||
size= 1;
|
||||
} else {
|
||||
size= blocks;
|
||||
}
|
||||
}
|
||||
iso_lsb(se->sec_count, size, 2);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write one section entry.
|
||||
* Usable for the Default Entry
|
||||
@ -930,6 +972,8 @@ int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
|
||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||
}
|
||||
|
||||
/* >>> check for non-automatic load size */;
|
||||
|
||||
if (t->boot_intvl_size[idx] > 65535) {
|
||||
if (img->platform_id == 0xef)
|
||||
iso_lsb(se->sec_count, 0, 2);
|
||||
@ -946,6 +990,9 @@ int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
|
||||
iso_lsb(se->block, t->boot_intvl_start[idx], 4);
|
||||
} else if (mode == 2) {
|
||||
app_idx = t->boot_appended_idx[idx];
|
||||
|
||||
/* >>> check for non-automatic load size */;
|
||||
|
||||
if (t->appended_part_size[app_idx] * 4 > 65535) {
|
||||
if (img->platform_id == 0xef)
|
||||
iso_lsb(se->sec_count, 0, 2);
|
||||
@ -956,7 +1003,8 @@ int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
|
||||
}
|
||||
iso_lsb(se->block, t->appended_part_start[app_idx], 4);
|
||||
} else {
|
||||
iso_lsb(se->sec_count, img->load_size, 2);
|
||||
write_section_load_size(img, se, (uint16_t) img->load_size,
|
||||
(off_t) t->bootsrc[idx]->sections[0].size, 0);
|
||||
iso_lsb(se->block, t->bootsrc[idx]->sections[0].block, 4);
|
||||
}
|
||||
|
||||
@ -1457,11 +1505,6 @@ int eltorito_writer_create(Ecma119Image *target)
|
||||
target->catalog->bootimages[idx]->appended_start;
|
||||
target->boot_intvl_size[idx] =
|
||||
target->catalog->bootimages[idx]->appended_size;
|
||||
if (((target->system_area_options >> 2) & 0x3f) == 0 &&
|
||||
(target->system_area_options & 3) == 1) {
|
||||
/* ISO will not be a partition. It can span the whole image. */
|
||||
target->pvd_size_is_total_size = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -85,6 +85,7 @@ struct el_torito_boot_image {
|
||||
unsigned char partition_type; /**< type of partition for HD-emul images */
|
||||
uint16_t load_seg; /**< Load segment for the initial boot image. */
|
||||
uint16_t load_size; /**< Number of sectors to load. */
|
||||
int load_size_full; /* 1= override load_size by image size */
|
||||
|
||||
/* Byte 1 of Validation Entry or Section Header Entry:
|
||||
0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */
|
||||
|
@ -325,6 +325,11 @@ typedef struct
|
||||
*/
|
||||
int aaip_version;
|
||||
|
||||
/**
|
||||
* Start block of loaded session.
|
||||
*/
|
||||
uint32_t session_lba;
|
||||
|
||||
/**
|
||||
* Number of blocks of the volume, as reported in the PVM.
|
||||
*/
|
||||
@ -371,7 +376,7 @@ typedef struct
|
||||
bit3= Invalid NM entry
|
||||
bit4= New SL entry found without previous CONTINUE flag
|
||||
bit5= Invalid SL entry
|
||||
bit6= Invalid SL entry, no child location
|
||||
bit6= Invalid CL entry, no child location / found in CL target
|
||||
bit7= Invalid PN entry
|
||||
bit8= Sparse files not supported
|
||||
bit9= SP entry found in a directory entry other than '.' entry of root
|
||||
@ -384,6 +389,7 @@ typedef struct
|
||||
bit16= Incomplete SL
|
||||
bit17= Charset conversion error
|
||||
bit18= Link without destination
|
||||
bit19= SL with a non-link file
|
||||
*/
|
||||
int rr_err_reported;
|
||||
int rr_err_repeated;
|
||||
@ -1415,6 +1421,7 @@ int iso_rr_msg_submit(_ImageFsData *fsdata, int rr_err_bit,
|
||||
* @param flag
|
||||
* bit0= this is the root node attribute load call
|
||||
* (parameter parent is not reliable for this)
|
||||
* bit1= this is a call caused by CL. Do not obey CL again.
|
||||
* @return
|
||||
* 2 node is still incomplete (multi-extent)
|
||||
* 1 success, 0 record ignored (not an error, can be a relocated dir),
|
||||
@ -1576,13 +1583,14 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
SuspIterator *iter;
|
||||
|
||||
|
||||
iter = susp_iter_new(fsdata->src, record, fsdata->len_skp,
|
||||
fsdata->msgid);
|
||||
iter = susp_iter_new(fsdata->src, record,
|
||||
fsdata->session_lba + fsdata->nblocks,
|
||||
fsdata->len_skp, fsdata->msgid);
|
||||
if (iter == NULL) {
|
||||
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||
}
|
||||
|
||||
while ((ret = susp_iter_next(iter, &sue)) > 0) {
|
||||
while ((ret = susp_iter_next(iter, &sue, 0)) > 0) {
|
||||
|
||||
/* ignore entries from different version */
|
||||
if (sue->version[0] != 1)
|
||||
@ -1699,7 +1707,17 @@ if (name != NULL && !namecont) {
|
||||
*/
|
||||
susp_iter_free(iter);
|
||||
free(name);
|
||||
if (flag & 1) {
|
||||
ret = iso_rr_msg_submit(fsdata, 3, ISO_NO_ROOT_DIR, 0,
|
||||
"Root directory is marked by RRIP RE as relocated");
|
||||
ret= ISO_NO_ROOT_DIR;
|
||||
goto ex;
|
||||
}
|
||||
{ret = 0; goto ex;} /* it's not an error */
|
||||
} else if (SUSP_SIG(sue, 'C', 'L') && (flag & 2)) {
|
||||
ret = iso_rr_msg_submit(fsdata, 6, ISO_WRONG_RR, 0,
|
||||
"Invalid CL entry, found in CL target");
|
||||
|
||||
} else if (SUSP_SIG(sue, 'C', 'L')) {
|
||||
/*
|
||||
* This entry is a placeholder for a relocated dir.
|
||||
@ -1710,7 +1728,7 @@ if (name != NULL && !namecont) {
|
||||
relocated_dir = iso_read_bb(sue->data.CL.child_loc, 4, NULL);
|
||||
if (relocated_dir == 0) {
|
||||
ret = iso_rr_msg_submit(fsdata, 6, ISO_WRONG_RR, 0,
|
||||
"Invalid SL entry, no child location");
|
||||
"Invalid CL entry, no child location");
|
||||
break;
|
||||
}
|
||||
} else if (SUSP_SIG(sue, 'P', 'N')) {
|
||||
@ -1979,14 +1997,17 @@ if (name != NULL && !namecont) {
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* Call with flag bit1 to prevent further CL relocation */
|
||||
ret = iso_file_source_new_ifs(fs, parent, (struct ecma119_dir_record*)
|
||||
buffer, src, 0);
|
||||
buffer, src, flag | 2);
|
||||
if (ret <= 0) {
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* but the real name is the name of the placeholder */
|
||||
ifsdata = (ImageFileSourceData*) (*src)->data;
|
||||
if (ifsdata->name != NULL)
|
||||
free(ifsdata->name);
|
||||
ifsdata->name = name;
|
||||
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
@ -2087,6 +2108,11 @@ if (name != NULL && !namecont) {
|
||||
|
||||
if (S_ISLNK(atts.st_mode)) {
|
||||
ifsdata->data.content = linkdest;
|
||||
} else if (linkdest != NULL) {
|
||||
ret = iso_rr_msg_submit(fsdata, 19, ISO_WRONG_RR_WARN, 0,
|
||||
"RRIP SL link destination with file that is not a link.");
|
||||
free(linkdest);
|
||||
linkdest = NULL;
|
||||
}
|
||||
|
||||
ifsrc->class = &ifs_class;
|
||||
@ -2392,13 +2418,14 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
||||
* In that case, we need to set info->len_skp to 15!!
|
||||
*/
|
||||
|
||||
iter = susp_iter_new(data->src, record, data->len_skp, data->msgid);
|
||||
iter = susp_iter_new(data->src, record, data->session_lba + data->nblocks,
|
||||
data->len_skp, data->msgid);
|
||||
if (iter == NULL) {
|
||||
ret = ISO_OUT_OF_MEM; goto ex;
|
||||
}
|
||||
|
||||
/* first entry must be an SP system use entry */
|
||||
ret = susp_iter_next(iter, &sue);
|
||||
ret = susp_iter_next(iter, &sue, 1);
|
||||
if (ret < 0) {
|
||||
/* error */
|
||||
susp_iter_free(iter);
|
||||
@ -2442,7 +2469,7 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
||||
* no?), but if we finally need it, it can be easily implemented in
|
||||
* the iterator, transparently for the rest of the code.
|
||||
*/
|
||||
while ((ret = susp_iter_next(iter, &sue)) > 0) {
|
||||
while ((ret = susp_iter_next(iter, &sue, 0)) > 0) {
|
||||
|
||||
/* ignore entries from different version */
|
||||
if (sue->version[0] != 1)
|
||||
@ -2589,6 +2616,9 @@ int read_pvm(_ImageFsData *data, uint32_t block)
|
||||
data->effective_time =
|
||||
iso_util_strcopy_untail((char*) pvm->vol_effective_time, 17);
|
||||
|
||||
data->session_lba = 0;
|
||||
if (block >= 16) /* The session begins 16 blocks before the PVD */
|
||||
data->session_lba = block - 16;
|
||||
data->nblocks = iso_read_bb(pvm->vol_space_size, 4, NULL);
|
||||
|
||||
rootdr = (struct ecma119_dir_record*) pvm->root_dir_record;
|
||||
@ -2641,14 +2671,6 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
||||
{ret = ISO_WRONG_EL_TORITO; goto ex;}
|
||||
}
|
||||
|
||||
/* check for a valid platform */
|
||||
if (ve->platform_id[0] != 0 && ve->platform_id[0] != 0xef) {
|
||||
iso_msg_submit(data->msgid, ISO_UNSUPPORTED_EL_TORITO, 0,
|
||||
"Unsupported El-Torito platform. Only 80x86 and EFI are "
|
||||
"supported. El-Torito info will be ignored.");
|
||||
{ret = ISO_UNSUPPORTED_EL_TORITO; goto ex;}
|
||||
}
|
||||
|
||||
/* ok, once we are here we assume it is a valid catalog */
|
||||
|
||||
/* parse the default entry */
|
||||
@ -3017,15 +3039,14 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
||||
} while (buffer[0] != 255);
|
||||
|
||||
/* 4. check if RR extensions are being used */
|
||||
ret = read_root_susp_entries(data, data->pvd_root_block);
|
||||
if (ret < 0) {
|
||||
goto fs_cleanup;
|
||||
}
|
||||
|
||||
/* user doesn't want to read RR extensions */
|
||||
if (opts->norock) {
|
||||
/* user doesn't want to read RR extensions */
|
||||
data->rr = RR_EXT_NO;
|
||||
} else {
|
||||
ret = read_root_susp_entries(data, data->pvd_root_block);
|
||||
if (ret < 0) {
|
||||
goto fs_cleanup;
|
||||
}
|
||||
data->rr = data->rr_version;
|
||||
}
|
||||
|
||||
@ -3906,10 +3927,12 @@ try_grub2_mbr:;
|
||||
|
||||
static
|
||||
int iso_analyze_partition_offset(IsoImage *image, IsoDataSource *src,
|
||||
uint64_t start_block, int flag)
|
||||
uint64_t start_block, uint64_t block_count,
|
||||
int flag)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *buf = NULL;
|
||||
uint32_t iso_size;
|
||||
off_t p_offset;
|
||||
struct ecma119_pri_vol_desc *pvm;
|
||||
struct iso_imported_sys_area *sai;
|
||||
@ -3922,11 +3945,14 @@ int iso_analyze_partition_offset(IsoImage *image, IsoDataSource *src,
|
||||
ret = src->read_block(src, p_offset + 16, buf);
|
||||
if (ret > 0) {
|
||||
pvm = (struct ecma119_pri_vol_desc *) buf;
|
||||
iso_size = iso_read_lsb(pvm->vol_space_size, 4);
|
||||
if (strncmp((char*) pvm->std_identifier, "CD001", 5) == 0 &&
|
||||
pvm->vol_desc_type[0] == 1 &&
|
||||
pvm->vol_desc_version[0] == 1 &&
|
||||
pvm->file_structure_version[0] == 1 &&
|
||||
iso_read_lsb(pvm->vol_space_size, 4) + p_offset == sai->image_size)
|
||||
(iso_size + p_offset == sai->image_size ||
|
||||
iso_size == block_count / 4))
|
||||
|
||||
sai->partition_offset = p_offset;
|
||||
}
|
||||
ret = 1;
|
||||
@ -4035,10 +4061,10 @@ int iso_analyze_mbr(IsoImage *image, IsoDataSource *src, int flag)
|
||||
part->start_block >= 64 && part->block_count >= 72 &&
|
||||
part->start_block <= 2048 &&
|
||||
part->start_block % 4 == 0 && part->block_count % 4 == 0 &&
|
||||
(part->start_block + part->block_count) / 4 == sai->image_size) {
|
||||
(part->start_block + part->block_count) / 4 <= sai->image_size) {
|
||||
|
||||
ret = iso_analyze_partition_offset(image, src, part->start_block,
|
||||
0);
|
||||
part->block_count, 0);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
@ -4343,10 +4369,10 @@ int iso_analyze_gpt(IsoImage *image, IsoDataSource *src, int flag)
|
||||
block_count = sai->gpt_req[0]->block_count;
|
||||
if (start_block >= 64 && block_count >= 72 &&
|
||||
start_block <= 2048 && start_block % 4 == 0 &&
|
||||
block_count % 4 == 0 &&
|
||||
(start_block + block_count) / 4 == sai->image_size) {
|
||||
block_count % 4 == 0) {
|
||||
|
||||
ret = iso_analyze_partition_offset(image, src, start_block, 0);
|
||||
ret = iso_analyze_partition_offset(image, src, start_block,
|
||||
block_count, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@ -4975,12 +5001,13 @@ int iso_impsysa_report(IsoImage *image, struct iso_impsysa_result *target,
|
||||
if (sa_type == 0) {
|
||||
if ((sao & 3) || sa_sub == 1 || sa_sub == 2) {
|
||||
strcat(msg, " MBR");
|
||||
if (sao & 1)
|
||||
strcat(msg, " protective-msdos-label");
|
||||
else if (sao & 2)
|
||||
if (sao & 2)
|
||||
strcat(msg, " isohybrid");
|
||||
else if (sa_sub == 1)
|
||||
else if (sao & 1)
|
||||
strcat(msg, " protective-msdos-label");
|
||||
else if (sa_sub == 1) {
|
||||
strcat(msg, " CHRP");
|
||||
}
|
||||
if ((sao & (1 << 14)) && !(sao & 2))
|
||||
strcat(msg, " grub2-mbr");
|
||||
sprintf(msg + strlen(msg), " cyl-align-%s",
|
||||
@ -5738,6 +5765,10 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
iso_filesystem_unref(fs);
|
||||
return ret;
|
||||
}
|
||||
if (newroot == NULL) {
|
||||
iso_filesystem_unref(fs);
|
||||
return ISO_NO_ROOT_DIR;
|
||||
}
|
||||
|
||||
/* Lookup character set even if no AAIP loading is enabled */
|
||||
ret = iso_file_source_get_aa_string(newroot, &aa_string, 2);
|
||||
@ -5853,6 +5884,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
boot_image->platform_id = data->platform_ids[idx];
|
||||
memcpy(boot_image->id_string, data->id_strings[idx], 28);
|
||||
memcpy(boot_image->selection_crit, data->selection_crits, 20);
|
||||
boot_image->appended_idx = -1;
|
||||
|
||||
catalog->bootimages[catalog->num_bootimages] = boot_image;
|
||||
boot_image = NULL;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
||||
* Copyright (c) 2009-2016 Thomas Schmitt
|
||||
* Copyright (c) 2009-2017 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -94,7 +94,7 @@ extern "C" {
|
||||
*/
|
||||
#define iso_lib_header_version_major 1
|
||||
#define iso_lib_header_version_minor 4
|
||||
#define iso_lib_header_version_micro 6
|
||||
#define iso_lib_header_version_micro 8
|
||||
|
||||
/**
|
||||
* Get version of the libisofs library at runtime.
|
||||
@ -2749,6 +2749,21 @@ int iso_write_opts_set_appended_as_apm(IsoWriteOpts *opts, int apm);
|
||||
*/
|
||||
int iso_write_opts_set_part_like_isohybrid(IsoWriteOpts *opts, int alike);
|
||||
|
||||
/**
|
||||
* Set the partition type of the MBR partition which represents the ISO
|
||||
* filesystem or at least protects it.
|
||||
* This is without effect if no such partition emerges by other settings or
|
||||
* if the partition type is prescribed mandatorily like 0xee for GPT protective
|
||||
* MBR or 0x96 for CHRP.
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param part_type
|
||||
* 0x00 to 0xff as desired partition type.
|
||||
* Any other value (e.g. -1) enables the default types of the various
|
||||
* occasions.
|
||||
* @since 1.4.8
|
||||
*/
|
||||
int iso_write_opts_set_iso_mbr_part_type(IsoWriteOpts *opts, int part_type);
|
||||
|
||||
/**
|
||||
* Inquire the start address of the file data blocks after having used
|
||||
@ -3836,6 +3851,26 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors);
|
||||
*/
|
||||
int el_torito_get_load_size(ElToritoBootImage *bootimg);
|
||||
|
||||
/**
|
||||
* State that the load size shall be the size of the boot image automatically.
|
||||
* This overrides el_torito_set_load_size().
|
||||
* @param bootimg
|
||||
* The image to to manipulate
|
||||
* @param mode
|
||||
* 0= use value of el_torito_set_load_size()
|
||||
* 1= determine value from boot image
|
||||
*/
|
||||
void el_torito_set_full_load(ElToritoBootImage *bootimg, int mode);
|
||||
|
||||
/**
|
||||
* Inquire the setting of el_torito_set_full_load().
|
||||
* @param bootimg
|
||||
* The image to inquire
|
||||
* @return
|
||||
* The mode set with el_torito_set_full_load().
|
||||
*/
|
||||
int el_torito_get_full_load(ElToritoBootImage *bootimg);
|
||||
|
||||
/**
|
||||
* Marks the specified boot image as not bootable
|
||||
*
|
||||
@ -8845,6 +8880,17 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
|
||||
(FAILURE, HIGH, -417) */
|
||||
#define ISO_BAD_GPT_GUID_MODE 0xE830FE5F
|
||||
|
||||
/** Unable to obtain root directory (FATAL,HIGH, -418) */
|
||||
#define ISO_NO_ROOT_DIR 0xF030FE5E
|
||||
|
||||
/** Zero sized, oversized, or mislocated SUSP CE area found
|
||||
(FAILURE, HIGH, -419) */
|
||||
#define ISO_SUSP_WRONG_CE_SIZE 0xE830FE5D
|
||||
|
||||
/** Multi-session would overwrite imported_iso interval
|
||||
(FAILURE, HIGH, -420) */
|
||||
#define ISO_MULTI_OVER_IMPORTED 0xE830FE5C
|
||||
|
||||
|
||||
/* Internal developer note:
|
||||
Place new error codes directly above this comment.
|
||||
|
@ -5,6 +5,7 @@ aaip_xinfo_func;
|
||||
el_torito_get_bootable;
|
||||
el_torito_get_boot_media_type;
|
||||
el_torito_get_boot_platform_id;
|
||||
el_torito_get_full_load;
|
||||
el_torito_get_id_string;
|
||||
el_torito_get_isolinux_options;
|
||||
el_torito_get_load_seg;
|
||||
@ -13,6 +14,7 @@ el_torito_get_selection_crit;
|
||||
el_torito_patch_isolinux_image;
|
||||
el_torito_seems_boot_info_table;
|
||||
el_torito_set_boot_platform_id;
|
||||
el_torito_set_full_load;
|
||||
el_torito_set_id_string;
|
||||
el_torito_set_isolinux_options;
|
||||
el_torito_set_load_seg;
|
||||
@ -328,6 +330,7 @@ iso_write_opts_set_hfsp_serial_number;
|
||||
iso_write_opts_set_hfsplus;
|
||||
iso_write_opts_set_iso1999;
|
||||
iso_write_opts_set_iso_level;
|
||||
iso_write_opts_set_iso_mbr_part_type;
|
||||
iso_write_opts_set_joliet;
|
||||
iso_write_opts_set_joliet_long_names;
|
||||
iso_write_opts_set_joliet_longer_paths;
|
||||
|
@ -547,6 +547,12 @@ const char *iso_error_to_msg(int errcode)
|
||||
return "Cannot derive GPT GUID from undefined pseudo-UUID volume timestamp";
|
||||
case ISO_BAD_GPT_GUID_MODE:
|
||||
return "Unrecognized GPT disk GUID setup mode";
|
||||
case ISO_NO_ROOT_DIR:
|
||||
return "Unable to obtain root directory";
|
||||
case ISO_SUSP_WRONG_CE_SIZE:
|
||||
return "Zero sized, oversized, or mislocated SUSP CE area found";
|
||||
case ISO_MULTI_OVER_IMPORTED:
|
||||
return "Multi-session would overwrite imported_iso interval";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ typedef struct susp_iterator SuspIterator;
|
||||
|
||||
SuspIterator *
|
||||
susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
|
||||
uint8_t len_skp, int msgid);
|
||||
uint32_t fs_blocks, uint8_t len_skp, int msgid);
|
||||
|
||||
/**
|
||||
* Get the next SUSP System User Entry using given iterator.
|
||||
@ -266,7 +266,8 @@ susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
|
||||
* @return
|
||||
* 1 on success, 0 if no more entries, < 0 error
|
||||
*/
|
||||
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue);
|
||||
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue,
|
||||
int flag);
|
||||
|
||||
/**
|
||||
* Free a given susp iterator.
|
||||
|
@ -35,6 +35,9 @@ struct susp_iterator
|
||||
IsoDataSource *src;
|
||||
int msgid;
|
||||
|
||||
/* Number of blocks in the ISO 9660 filesystem */
|
||||
uint32_t fs_blocks;
|
||||
|
||||
/* block and offset for next continuation area */
|
||||
uint32_t ce_block;
|
||||
uint32_t ce_off;
|
||||
@ -47,7 +50,7 @@ struct susp_iterator
|
||||
|
||||
SuspIterator*
|
||||
susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
|
||||
uint8_t len_skp, int msgid)
|
||||
uint32_t fs_blocks, uint8_t len_skp, int msgid)
|
||||
{
|
||||
int pad = (record->len_fi[0] + 1) % 2;
|
||||
struct susp_iterator *iter = malloc(sizeof(struct susp_iterator));
|
||||
@ -60,6 +63,7 @@ susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
|
||||
iter->size = record->len_dr[0] - record->len_fi[0] - 33 - pad;
|
||||
iter->src = src;
|
||||
iter->msgid = msgid;
|
||||
iter->fs_blocks = fs_blocks;
|
||||
|
||||
iter->ce_len = 0;
|
||||
iter->buffer = NULL;
|
||||
@ -67,12 +71,30 @@ susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
|
||||
return iter;
|
||||
}
|
||||
|
||||
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
|
||||
/* More than 1 MiB in a single file's CE area is suspicious */
|
||||
#define ISO_SUSP_MAX_CE_BYTES (1024 * 1024)
|
||||
|
||||
|
||||
/* @param flag bit0 = First call on root:
|
||||
Not yet clear whether this is SUSP at all
|
||||
*/
|
||||
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue,
|
||||
int flag)
|
||||
{
|
||||
struct susp_sys_user_entry *entry;
|
||||
|
||||
entry = (struct susp_sys_user_entry*)(iter->base + iter->pos);
|
||||
|
||||
if (flag & 1) {
|
||||
/* Yet unclear whether it is SUSP at all */
|
||||
if (iter->size < 7)
|
||||
return 0;
|
||||
if (!SUSP_SIG(entry, 'S', 'P'))
|
||||
return 0;
|
||||
if (entry->len_sue[0] < 7)
|
||||
return 0;
|
||||
/* Looks like SUSP enough to pass the further processing here. */
|
||||
}
|
||||
if ( (iter->pos + 4 > iter->size) || (SUSP_SIG(entry, 'S', 'T'))) {
|
||||
|
||||
/*
|
||||
@ -81,22 +103,31 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
|
||||
* (IEEE 1281, SUSP. section 4)
|
||||
*/
|
||||
if (iter->ce_len) {
|
||||
uint32_t block, nblocks;
|
||||
uint32_t block, nblocks, skipped_blocks, skipped_bytes;
|
||||
|
||||
/* A CE has found, there is another continuation area */
|
||||
nblocks = DIV_UP(iter->ce_off + iter->ce_len, BLOCK_SIZE);
|
||||
/* A CE was found, there is another continuation area */
|
||||
skipped_blocks = iter->ce_off / BLOCK_SIZE;
|
||||
skipped_bytes = skipped_blocks * BLOCK_SIZE;
|
||||
nblocks = DIV_UP(iter->ce_off - skipped_bytes + iter->ce_len,
|
||||
BLOCK_SIZE);
|
||||
if (nblocks <= 0 || iter->ce_len > ISO_SUSP_MAX_CE_BYTES)
|
||||
return ISO_SUSP_WRONG_CE_SIZE;
|
||||
if (((uint64_t) iter->ce_block) + skipped_blocks + nblocks >
|
||||
(uint64_t) iter->fs_blocks)
|
||||
return ISO_SUSP_WRONG_CE_SIZE;
|
||||
iter->buffer = realloc(iter->buffer, nblocks * BLOCK_SIZE);
|
||||
|
||||
/* read all blocks needed to cache the full CE */
|
||||
/* Read blocks needed to cache the given CE area range */
|
||||
for (block = 0; block < nblocks; ++block) {
|
||||
int ret;
|
||||
ret = iter->src->read_block(iter->src, iter->ce_block + block,
|
||||
iter->buffer + block * BLOCK_SIZE);
|
||||
ret = iter->src->read_block(iter->src,
|
||||
iter->ce_block + skipped_blocks + block,
|
||||
iter->buffer + block * BLOCK_SIZE);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
iter->base = iter->buffer + iter->ce_off;
|
||||
iter->base = iter->buffer + (iter->ce_off - skipped_bytes);
|
||||
iter->pos = 0;
|
||||
iter->size = iter->ce_len;
|
||||
iter->ce_len = 0;
|
||||
@ -134,10 +165,10 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
|
||||
}
|
||||
|
||||
/* we don't want to return CE entry to the user */
|
||||
return susp_iter_next(iter, sue);
|
||||
return susp_iter_next(iter, sue, 0);
|
||||
} else if (SUSP_SIG(entry, 'P', 'D')) {
|
||||
/* skip padding */
|
||||
return susp_iter_next(iter, sue);
|
||||
return susp_iter_next(iter, sue, 0);
|
||||
}
|
||||
|
||||
*sue = entry;
|
||||
@ -374,12 +405,18 @@ int read_rr_SL(struct susp_sys_user_entry *sl, char **dest, int *cont)
|
||||
if (*cont == 1) {
|
||||
/* new component */
|
||||
size_t size = strlen(*dest);
|
||||
int has_slash;
|
||||
|
||||
*dest = realloc(*dest, strlen(*dest) + len + 2);
|
||||
if (*dest == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
/* it is a new compoenent, add the '/' */
|
||||
if ((*dest)[size-1] != '/') {
|
||||
has_slash = 0;
|
||||
if (size > 0)
|
||||
if ((*dest)[size - 1] == '/')
|
||||
has_slash = 1;
|
||||
if (!has_slash) {
|
||||
(*dest)[size] = '/';
|
||||
(*dest)[size+1] = '\0';
|
||||
}
|
||||
@ -462,24 +499,27 @@ int read_aaip_AA(struct susp_sys_user_entry *sue,
|
||||
if (*is_done) {
|
||||
|
||||
/* To coexist with Apple ISO :
|
||||
Gracefully react on eventually trailing Apple AA
|
||||
Gracefully react on possibly trailing Apple AA
|
||||
*/
|
||||
if (sue->version[0] != 1 || sue->len_sue[0] == 7)
|
||||
return ISO_SUCCESS;
|
||||
|
||||
return ISO_WRONG_RR;
|
||||
}
|
||||
|
||||
|
||||
/* Eventually create or grow storage */
|
||||
if (*aa_size == 0 || *aa_string == NULL) {
|
||||
|
||||
/* Gracefully react on eventually leading Apple AA
|
||||
/* Gracefully react on possibly leading Apple AA
|
||||
*/
|
||||
if (sue->version[0] != 1 || sue->len_sue[0] < 9) {
|
||||
if (sue->version[0] != 1 || sue->len_sue[0] < 9)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* A valid AAIP AA entry has 5 header bytes and at least 1 component byte
|
||||
*/
|
||||
if (sue->len_sue[0] < 6)
|
||||
return ISO_WRONG_RR;
|
||||
|
||||
/* Possibly create or grow storage */
|
||||
if (*aa_size == 0 || *aa_string == NULL) {
|
||||
*aa_size = *aa_len + sue->len_sue[0];
|
||||
*aa_string = calloc(*aa_size, 1);
|
||||
*aa_len = 0;
|
||||
@ -535,7 +575,12 @@ int read_aaip_AL(struct susp_sys_user_entry *sue,
|
||||
if (sue->version[0] != 1)
|
||||
return ISO_WRONG_RR;
|
||||
|
||||
/* Eventually create or grow storage */
|
||||
/* A valid AL entry has 5 header bytes and at least 1 component byte
|
||||
*/
|
||||
if (sue->len_sue[0] < 6)
|
||||
return ISO_WRONG_RR;
|
||||
|
||||
/* Possibly create or grow storage */
|
||||
if (*aa_size == 0 || *aa_string == NULL) {
|
||||
*aa_size = *aa_len + sue->len_sue[0];
|
||||
*aa_string = calloc(*aa_size, 1);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Vreixo Formoso
|
||||
* Copyright (c) 2010 - 2016 Thomas Schmitt
|
||||
* Copyright (c) 2010 - 2017 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -108,11 +108,14 @@ void iso_compute_cyl_head_sec(uint64_t img_blocks, int hpc, int sph,
|
||||
}
|
||||
|
||||
/* @param flag bit0= The path contains instructions for the interval reader
|
||||
@return ISO_SUCCESS = ok, partition will be written
|
||||
ISO_SUCCESS + 1 = interval which shall be kept in place
|
||||
else : error code
|
||||
*/
|
||||
static int compute_partition_size(Ecma119Image *t, char *disk_path,
|
||||
uint32_t *size, int flag)
|
||||
{
|
||||
int ret;
|
||||
int ret, keep;
|
||||
off_t num;
|
||||
struct stat stbuf;
|
||||
struct iso_interval_reader *ivr;
|
||||
@ -124,8 +127,11 @@ static int compute_partition_size(Ecma119Image *t, char *disk_path,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*size = (byte_count + BLOCK_SIZE - 1) / BLOCK_SIZE;
|
||||
keep = iso_interval_reader_keep(t, ivr, 0);
|
||||
iso_interval_reader_destroy(&ivr, 0);
|
||||
return ISO_SUCCESS;
|
||||
if (keep < 0)
|
||||
return keep;
|
||||
return ISO_SUCCESS + (keep > 0);
|
||||
}
|
||||
|
||||
*size = 0;
|
||||
@ -148,6 +154,7 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
|
||||
{
|
||||
int ret, i, sa_type, cyl_align, cyl_size = 0;
|
||||
uint32_t pos, size, add_pos = 0;
|
||||
off_t start_byte, byte_count;
|
||||
|
||||
sa_type = (t->system_area_options >> 2) & 0x3f;
|
||||
cyl_align = (t->system_area_options >> 8) & 0x3;
|
||||
@ -168,6 +175,20 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
|
||||
t->opts->appended_part_flags[i]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret == ISO_SUCCESS + 1) {
|
||||
/* Interval from imported_iso in add-on session */
|
||||
t->appended_part_prepad[i] = 0;
|
||||
ret = iso_interval_reader_start_size(t,
|
||||
t->opts->appended_partitions[i],
|
||||
&start_byte, &byte_count, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
t->appended_part_start[i] = start_byte / 2048;
|
||||
t->appended_part_size[i] = size;
|
||||
t->opts->iso_mbr_part_type = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
add_pos = 0;
|
||||
if (sa_type == 3 && (pos % ISO_SUN_CYL_SIZE)) {
|
||||
add_pos = ISO_SUN_CYL_SIZE - (pos % ISO_SUN_CYL_SIZE);
|
||||
@ -184,7 +205,7 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
|
||||
}
|
||||
t->appended_part_size[i] = size;
|
||||
pos += add_pos + size;
|
||||
t->total_size += (add_pos + size) * 2048;
|
||||
t->total_size += (((off_t) add_pos) + size) * 2048;
|
||||
if (flag & 1)
|
||||
t->curblock = pos;
|
||||
}
|
||||
@ -192,6 +213,19 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
|
||||
}
|
||||
|
||||
|
||||
static int mbr_part_slot_is_unused(uint8_t *slot)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
if (slot[i] != 0)
|
||||
break;
|
||||
if (i >= 16)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* @param flag
|
||||
bit1= partition_offset and partition_size are counted in
|
||||
blocks of 512 rather than 2048
|
||||
@ -287,7 +321,7 @@ int make_grub_msdos_label(uint32_t img_blocks, int sph, int hpc,
|
||||
buf[510] = 0x55;
|
||||
buf[511] = 0xAA;
|
||||
}
|
||||
if (!(flag & 2)) {
|
||||
if ((!(flag & 2)) && part_type != 0xee && part_type != 0xef) {
|
||||
/* 3) Put 0x80 (for bootable partition), */
|
||||
*(wpt++) = 0x80;
|
||||
} else {
|
||||
@ -1777,7 +1811,7 @@ static void iso_dummy_mbr_partition(uint8_t *buf, int mode)
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 };
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (buf[446 + 16 * i + 4] == 0x00) {
|
||||
if (mbr_part_slot_is_unused(buf + 446 + 16 * i)) {
|
||||
memcpy(buf + 446 + 16 * i, dummy_entry, 16);
|
||||
return;
|
||||
}
|
||||
@ -1918,6 +1952,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
pml_blocks = gpt_blocks;
|
||||
} else {
|
||||
part_type = 0xcd;
|
||||
if (t->opts->iso_mbr_part_type >= 0 &&
|
||||
t->opts->iso_mbr_part_type <= 255)
|
||||
part_type= t->opts->iso_mbr_part_type;
|
||||
pml_blocks = img_blocks;
|
||||
}
|
||||
ret = make_grub_msdos_label(pml_blocks, t->partition_secs_per_head,
|
||||
@ -1942,8 +1979,12 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
|
||||
if (gpt_count > 0 || apm_count > 0)
|
||||
part_type = 0x00;
|
||||
else
|
||||
else {
|
||||
part_type = 0x17;
|
||||
if (t->opts->iso_mbr_part_type >= 0 &&
|
||||
t->opts->iso_mbr_part_type <= 255)
|
||||
part_type= t->opts->iso_mbr_part_type;
|
||||
}
|
||||
|
||||
if (t->opts->appended_as_gpt && t->have_appended_partitions) {
|
||||
part_type = 0xee;
|
||||
@ -1985,9 +2026,13 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
} else if ((t->opts->partition_offset > 0 || will_append) &&
|
||||
sa_type == 0 && t->mbr_req_count == 0) {
|
||||
/* Write a simple partition table. */
|
||||
part_type = 0xcd;
|
||||
if (t->opts->iso_mbr_part_type >= 0 &&
|
||||
t->opts->iso_mbr_part_type <= 255)
|
||||
part_type= t->opts->iso_mbr_part_type;
|
||||
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
|
||||
t->partition_heads_per_cyl,
|
||||
(uint8_t) 0xcd, buf, 2);
|
||||
(uint8_t) part_type, buf, 2);
|
||||
if (ret != ISO_SUCCESS) /* error should never happen */
|
||||
return ISO_ASSERT_FAILURE;
|
||||
risk_of_ee = 1;
|
||||
@ -2007,7 +2052,11 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
} else if (t->opts->partition_offset == 0) {
|
||||
/* Re-write partion entry 1 : start at 0, type Linux */
|
||||
blk = ((uint64_t) img_blocks) * 4 - t->post_iso_part_pad / 512;
|
||||
ret = write_mbr_partition_entry(1, 0x83, (uint64_t) 0, blk,
|
||||
part_type = 0x83;
|
||||
if (t->opts->iso_mbr_part_type >= 0 &&
|
||||
t->opts->iso_mbr_part_type <= 255)
|
||||
part_type= t->opts->iso_mbr_part_type;
|
||||
ret = write_mbr_partition_entry(1, part_type, (uint64_t) 0, blk,
|
||||
t->partition_secs_per_head, t->partition_heads_per_cyl,
|
||||
buf, 2);
|
||||
if (ret < 0)
|
||||
@ -2081,13 +2130,18 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
/* >>> ??? check for GPT magic number at byte 512 ff. ? */;
|
||||
|
||||
if (sa_type == 0 && ((t->system_area_options & 3) || risk_of_ee) &&
|
||||
(t->opts->part_like_isohybrid || t->gpt_req_count == 0)) {
|
||||
(t->opts->part_like_isohybrid || t->gpt_req_count == 0) &&
|
||||
t->opts->iso_mbr_part_type != 0xee) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (buf[446 + 16 * i + 4] == 0xee) {
|
||||
iso_msgs_submit(0,
|
||||
"Prevented partition type 0xEE in MBR without GPT",
|
||||
0, "WARNING", 0);
|
||||
buf[446 + 16 * i + 4] = 0xcd;
|
||||
part_type = 0xcd;
|
||||
if (t->opts->iso_mbr_part_type >= 0 &&
|
||||
t->opts->iso_mbr_part_type <= 255)
|
||||
part_type= t->opts->iso_mbr_part_type;
|
||||
buf[446 + 16 * i + 4] = (uint8_t) part_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2095,7 +2149,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
if (sa_type == 0 && (
|
||||
(t->system_area_options & 3) ||
|
||||
(t->system_area_options & (1 << 14)) ||
|
||||
(((t->system_area_options >> 2) & 0x3f) == 2 &&
|
||||
(((t->system_area_options >> 10) & 15) != 1 &&
|
||||
(t->system_area_options & (1 << 15)))
|
||||
)) {
|
||||
/* This is an MBR which shall have a bootable/active flag
|
||||
@ -2106,7 +2160,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
break;
|
||||
if (i >= 4) { /* no bootable/active flag set yet */
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (buf[446 + 16 * i + 4] != 0x00 &&
|
||||
if ((!mbr_part_slot_is_unused(buf + 446 + 16 * i)) &&
|
||||
buf[446 + 16 * i + 4] != 0xee &&
|
||||
buf[446 + 16 * i + 4] != 0xef) {
|
||||
buf[446 + 16 * i] |= 0x80;
|
||||
@ -2120,6 +2174,14 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
|
||||
}
|
||||
}
|
||||
|
||||
if ((((t->system_area_options >> 2) & 0x3f) == 0 &&
|
||||
(t->system_area_options & 3) == 1) ||
|
||||
t->opts->partition_offset > 0) {
|
||||
/* Protective MBR || partition offset */
|
||||
/* ISO will not be a partition. It can span the whole image. */
|
||||
t->pvd_size_is_total_size = 1;
|
||||
}
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2475,7 +2537,7 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
|
||||
0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b
|
||||
};
|
||||
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
int i, ret, do_apm = 0, do_gpt = 0, index, already_in_gpt;
|
||||
int i, ret, do_apm = 0, do_gpt = 0, index, already_in_gpt = 0;
|
||||
uint8_t gpt_name[72], *type_uuid;
|
||||
|
||||
#ifndef Libisofs_appended_partitions_inlinE
|
||||
@ -2821,10 +2883,12 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
{
|
||||
Ecma119Image *t;
|
||||
IsoFileSrc *src;
|
||||
int ret, will_have_gpt = 0, with_chrp = 0, i;
|
||||
int ret, will_have_gpt = 0, with_chrp = 0, i, part_type, keep;
|
||||
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
static uint64_t gpt_flags = (((uint64_t) 1) << 60) | 1;
|
||||
uint8_t gpt_name[72];
|
||||
uint64_t part_start;
|
||||
off_t start_byte, byte_count;
|
||||
|
||||
/* <<< ??? Move to system_area.h and publish as macro ? */
|
||||
static uint8_t efi_sys_uuid[16] = {
|
||||
@ -2842,6 +2906,7 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
will_have_gpt = 1;
|
||||
|
||||
if (t->opts->efi_boot_partition != NULL) {
|
||||
keep = 0;
|
||||
if (t->efi_boot_part_filesrc != NULL) {
|
||||
/* A file in the emerging ISO image shall store its content
|
||||
as prepended partition.
|
||||
@ -2853,23 +2918,35 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
src->sections[i].block = t->curblock + t->efi_boot_part_size;
|
||||
t->efi_boot_part_size += (src->sections[i].size + 2047) / 2048;
|
||||
}
|
||||
part_start = t->curblock * 4;
|
||||
} else {
|
||||
ret = compute_partition_size(t, t->opts->efi_boot_partition,
|
||||
&(t->efi_boot_part_size),
|
||||
t->opts->efi_boot_part_flag & 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
part_start = t->curblock * 4;
|
||||
if (ret == ISO_SUCCESS + 1) {
|
||||
/* Interval from imported_iso in add-on session will be kept */
|
||||
ret = iso_interval_reader_start_size(t,
|
||||
t->opts->efi_boot_partition,
|
||||
&start_byte, &byte_count, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
part_start = start_byte / 512;
|
||||
keep = 1;
|
||||
}
|
||||
}
|
||||
memset(gpt_name, 0, 72);
|
||||
strcpy((char *) gpt_name, "EFI boot partition");
|
||||
iso_ascii_utf_16le(gpt_name);
|
||||
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
|
||||
((uint64_t) t->curblock) * 4,
|
||||
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count), part_start,
|
||||
((uint64_t) t->efi_boot_part_size) * 4,
|
||||
efi_sys_uuid, zero_uuid, gpt_flags, gpt_name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
t->curblock += t->efi_boot_part_size;
|
||||
if (!keep)
|
||||
t->curblock += t->efi_boot_part_size;
|
||||
}
|
||||
|
||||
if (with_chrp) {
|
||||
@ -2884,36 +2961,59 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
part_start = t->curblock * 4;
|
||||
keep = 0;
|
||||
if (t->opts->prep_partition != NULL) {
|
||||
ret = compute_partition_size(t, t->opts->prep_partition,
|
||||
&(t->prep_part_size),
|
||||
t->opts->prep_part_flag & 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret == ISO_SUCCESS + 1) {
|
||||
/* Interval from imported_iso in add-on session will be kept */
|
||||
ret = iso_interval_reader_start_size(t,
|
||||
t->opts->prep_partition,
|
||||
&start_byte, &byte_count, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
part_start = start_byte / 512;
|
||||
keep = 1;
|
||||
}
|
||||
}
|
||||
if (t->prep_part_size > 0 || t->opts->fat || will_have_gpt) {
|
||||
/* Protecting MBR entry for ISO start or whole ISO */
|
||||
part_type = 0xcd;
|
||||
if (t->opts->iso_mbr_part_type >= 0 &&
|
||||
t->opts->iso_mbr_part_type <= 255)
|
||||
part_type= t->opts->iso_mbr_part_type;
|
||||
if (will_have_gpt)
|
||||
part_type = 0xee;
|
||||
ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count),
|
||||
will_have_gpt ? (uint64_t) 1 :
|
||||
((uint64_t) t->opts->partition_offset) * 4,
|
||||
(uint64_t) 0,
|
||||
will_have_gpt ? 0xee : 0xcd, 0, 0);
|
||||
(uint64_t) 0, part_type, 0, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
if (t->prep_part_size > 0) {
|
||||
ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count),
|
||||
((uint64_t) t->curblock) * 4,
|
||||
ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count), part_start,
|
||||
((uint64_t) t->prep_part_size) * 4,
|
||||
0x41, 0, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
t->curblock += t->prep_part_size;
|
||||
if (!keep) {
|
||||
t->curblock += t->prep_part_size;
|
||||
part_start = t->curblock * 4;
|
||||
} else {
|
||||
part_start += t->prep_part_size * 4;
|
||||
}
|
||||
} else {
|
||||
part_start = t->curblock * 4;
|
||||
}
|
||||
if (t->prep_part_size > 0 || t->opts->fat) {
|
||||
/* FAT partition or protecting MBR entry for ISO end */
|
||||
ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count),
|
||||
((uint64_t) t->curblock) * 4, (uint64_t) 0,
|
||||
part_start, (uint64_t) 0,
|
||||
t->opts->fat ? 0x0c : 0xcd, 0, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
Reference in New Issue
Block a user