[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Proposal v2: fs/iso9660: Prevent skipping CE or ST at start of conti
From: |
Thomas Schmitt |
Subject: |
Re: Proposal v2: fs/iso9660: Prevent skipping CE or ST at start of continuation area |
Date: |
Mon, 09 Jan 2023 10:32:48 +0100 |
Hi,
Lidong Chen wrote:
> Thanks for the clarification. I created a new patch for the fix and added
> you as the “Signed-off-by”.
> My question is how to test it.
I just sent libisofs into an endless recursion loop. Grrr.
For this i created a small ISO with a file which surely needs a CE, changed
its fields so that it points to itself, and attempted to load it by xorriso.
(At least it ends by SIGSEGV on an exhausted stack and does not cycle
endlessly.)
--------------------------------------------------------------------------
ISO creation:
# A dummy file as payload
echo x >x
# 250 fattr characters to surely exceed the size of a directory entry
long_string=0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
# Create ISO with the payload file and attached fattr named user.dummy
test -e ce_loop.iso && rm ce_loop.iso
xorriso -outdev ce_loop.iso \
-xattr on \
-map x /x \
-setfattr user.dummy "$long_string" /x -- \
-padding 0
Next i determined by a hex dumper the location of the only Rock Ridge
entry NM and then the location of the next following CE entry (the first
CE belongs to the root directory):
Byte 102734 decimal = 50 * 2048 + 334 = LBA 0x32 + Offset 0x014e
The size of the continuation area is 270 = 0x010e
The length of CE is 28 = 0x1c
So i patched the own address and size of the CE entry into its fields:
# The block address (little endian and big endian)
echo $'\x32' | dd bs=1 seek=102738 count=1 conv=notrunc of=ce_loop.iso
echo $'\x32' | dd bs=1 seek=102745 count=1 conv=notrunc of=ce_loop.iso
# The byte offset in that block
echo $'\x4e'$'\x01' | dd bs=1 seek=102746 count=2 conv=notrunc of=ce_loop.iso
echo $'\x01'$'\x4e' | dd bs=1 seek=102752 count=2 conv=notrunc of=ce_loop.iso
# The new size of the CE area is the length of the CE entry
echo $'\x1c' | dd bs=1 seek=102754 count=1 conv=notrunc of=ce_loop.iso
echo $'\x1c' | dd bs=1 seek=102761 count=1 conv=notrunc of=ce_loop.iso
# Zeroize the higher valued bytes of the length field
dd if=/dev/zero bs=1 seek=102755 count=6 conv=notrunc of=ce_loop.iso
This really bad CE entry then looks in the hex dump like:
00019140 : 00 7b 01 09 08 08 1c 00 4e 4d 06 01 00 78 43 45
{ N M x C E
102720 : 0 123 1 9 8 8 28 0 78 77 6 1 0 120 67 69
00019150 : 1c 01 32 00 00 00 00 00 00 32 4e 01 00 00 00 00
2 2 N
102736 : 28 1 50 0 0 0 0 0 0 50 78 1 0 0 0 0
00019160 : 01 4e 1c 00 00 00 00 00 00 1c 00 00 00 00 00 00
N
102752 : 1 78 28 0 0 0 0 0 0 28 0 0 0 0 0 0
(Note: 00019140 is hex, not octal)
--------------------------------------------------------------------------
I will first try to fix libisofs before i upload this gremlin somewhere.
If you want to try in advance, run above shell commands and check whether
a hex editor shows the expected bytes afterwards. (xorriso is supposed to
be reproducible in respect to sizes and locations. Very old versions might
not fulfill that expectation, though.)
Have a nice day :)
Thomas