Compare commits

..

43 Commits

Author SHA1 Message Date
bdfd4c4a37 Updated changelog. 2017-09-12 12:05:32 +02:00
dfc6de9f79 Version leap to 1.4.8. 2017-09-12 11:58:56 +02:00
7234425502 Updated changelog. 2017-09-12 11:51:16 +02:00
4e5a54c2f9 Swapped at recognition time the precendence of MBR properties "isohybrid" and "protective-msdos-label" 2017-09-09 16:36:43 +02:00
028f9275d3 Throw error if imported_iso interval would be overwritten by multi-session 2017-08-26 11:47:14 +02:00
cace41ec16 Enabled partition intervals with source "imported_iso" with ISO growing 2017-08-24 12:19:54 +02:00
e599a575dc Closed a memory leak about RRIP CL following 2017-08-21 19:43:19 +02:00
78b0a7b111 Disallowed RRIP CL chaining in order to break any endless loops. Debian bug 872761. Thanks Jakub Wilk and American Fuzzy Lop. 2017-08-21 19:41:20 +02:00
a7152f5794 Correcting previous commit for supporting multi-session 2017-08-21 12:34:13 +02:00
2a64d89e6e Refuse to read CE data blocks from after the end of ISO filesystem 2017-08-19 16:55:08 +02:00
31088d9acc Avoid to read blocks from start of CE area which do not belong to the given file 2017-08-19 14:54:23 +02:00
91490d5f34 Preventing use of zero sized SUSP CE entry which causes SIGSEGV. Debian bug 872590. Thanks Jakub Wilk and American Fuzzy Lop. 2017-08-19 11:08:02 +02:00
661b68ce8c Preventing buffer overflow with AAIP AL entry of insufficient size. Debian bug 872545. Thanks Jakub Wilk and American Fuzzy Lop. 2017-08-18 14:56:50 +02:00
16bde11076 Preventing memory leak caused by RRIP SL entry without PX entry that marks the file as symbolic link 2017-08-18 11:11:05 +02:00
36c8800ff3 Preventing buffer underread with empty RRIP SL component. Debian bug 872475. Thanks Jakub Wilk and American Fuzzy Lop. 2017-08-18 10:56:59 +02:00
860a91dd2f Preventing NULL dereference if root directory bears a RRIP RE entry 2017-08-17 08:49:28 +02:00
280108d2d5 Updated change log 2017-08-14 18:08:48 +02:00
1e40ed3fab Bug fix: Keeping and patching of loaded boot images failed. Regression by version 1.4.4. 2017-08-14 17:51:05 +02:00
e19a338a09 Re-added two empty lines which were lost by previous commit 2017-08-13 14:51:39 +02:00
c6e4035918 Added boot sector knowledge gained from Natalia Portillo 2017-08-13 13:34:53 +02:00
18ab6019bc Let ISO size cover appended partitions if --protective-msdos-label or nonzero -partition_offset is given 2017-07-02 15:11:20 +02:00
6282bbc0bc Bug fix: Bit 15 of iso_write_opts_set_system_area did not work with generic MBR 2017-06-29 23:06:07 +02:00
d7737e3ed5 Removed ban on reading El Torito platform ids other than 0 and 0xef 2017-06-03 20:23:54 +02:00
fb8697081b Reacted on harmless compiler warning about uninitialized variable. 2017-04-25 12:11:33 +02:00
0e7300b1a8 Clarified meaning of MBR partition boot flag 2017-04-10 10:02:05 +02:00
94e4bfb42b Adapted recognizing of partition offset to the changes of rev afb10aa / 1348 2017-04-09 20:58:45 +02:00
86f6ffc9c9 Let iso_mbr_part_type 0xee override ban on 0xee without GPT 2017-03-19 11:14:49 +01:00
5600f3d726 When deciding boot flag, consider MBR partition slot empty only if entirely 0 2017-02-27 18:27:59 +01:00
e66b9bfe0c New API call iso_write_opts_set_iso_mbr_part_type() 2017-02-27 09:59:34 +01:00
094b3f7546 Updated copyright year in system_area.c 2017-01-24 13:00:11 +01:00
5c1c5cd964 Bug fix: Appended partitions of size >= 4 GiB led to abort with error message "FATAL : ISO overwrite". Thanks to Sven Haardiek. 2017-01-24 10:43:10 +01:00
215280448f Bug fix: Protective MBR for GPT could emerge with boot flag set. 2017-01-03 12:54:54 +01:00
3043b5f660 Enabled recognition of partition offset of grub-mkrescue-sed.sh mode "gpt_appended" 2016-12-25 15:46:11 +01:00
afb10aac3b Claiming full output size in first PVD if partition offset is non-zero 2016-12-25 10:05:26 +01:00
76181d0aa3 Restricted volume size of PVD with non-zero partition offset to filesystem size even if the first PVD claims the whole output size 2016-12-25 10:00:07 +01:00
8ec75eea6a Bug fix: Non-SUSP data in System Use Area prevented image loading if Rock Ridge was enabled. Thanks to Jonathan Dowland. 2016-11-23 22:52:11 +01:00
01020ef544 Committed missing part of rev dc6cd94/1342 2016-11-23 22:07:21 +01:00
2961bdef9f Updated change log 2016-11-13 10:20:24 +01:00
ed209e0b6e Mentioned Vladimir Serbinenko in libisofs copyright list 2016-11-13 10:13:47 +01:00
dc6cd946ba New API calls el_torito_set_full_load(), el_torito_get_full_load() 2016-11-13 10:05:18 +01:00
c51efce8d1 Bug fix: iso_read_opts_set_no_rockridge() did not prevent reading of root SUSP 2016-11-13 09:52:25 +01:00
8bf32d8d14 Prepared some of the documentation for move to dev.lovelyhq.com 2016-11-13 09:39:53 +01:00
561e2a6aaa Version leap to 1.4.7 2016-09-16 20:58:19 +02:00
17 changed files with 782 additions and 128 deletions

View File

@ -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

View File

@ -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
===============================================================================

View File

@ -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`

View File

@ -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
| |

View File

@ -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
View 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 -

View File

@ -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);

View File

@ -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_*/

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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";
}

View File

@ -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.

View File

@ -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);

View File

@ -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;