[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

mkisofs hangs with -graft-points + -M



Hi all,

I received a very good bug report from Radek Pospisil
about a problem he had with mkisofs. He used it together
with my root patch for backup purposes, but the same problem
can be triggered with the unpatched mkisofs from cdrtools 2.01a23.

If an incremental backup was made where one of the directories
in the existing ISO image had an odd name length between
111 and 135, then the mkisofs invocation that scans that
image hangs. It is important that -graft-points is used on
that long directory name, something that the new -root
option does implicitly.

Here's how this can be reproduced with cdrtools 2.01a23:

patrick@gollum(/tmp)$ mkdir
12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
patrick@gollum(/tmp)$
/usr/local/cdrtools-2.01/mkisofs/OBJ/i686-linux-cc/mkisofs -R -o 1.iso
-graft-points
1/12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345=12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
patrick@gollum(/tmp)$ ll 1.iso 
-rw-r--r--    1 patrick  patrick    364544 Jan  6 20:31 1.iso
patrick@gollum(/tmp)$
/usr/local/cdrtools-2.01/mkisofs/OBJ/i686-linux-cc/mkisofs -R -o 2.iso
-M 1.iso -C 0,364544 /dev/null
Rock Ridge signatures found

At this point mkisofs hangs and must be aborted.

Here's the content of the image that causes the problem:

root@gollum(~)# mount -o loop /tmp/1.iso /mnt
root@gollum(~)# ll /mnt/
total 2
dr-xr-xr-x    3 patrick  patrick      2048 Jan  6 20:31 1
root@gollum(~)# ll /mnt/1
total 2
dr-xr-xr-x    2 patrick  patrick      2048 Jan  6 20:31
12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345

valgrind on Linux reports two invalid memory reads of the same
byte, which happens to be
				len -= pnt[2];
				pnt += pnt[2];
in a while loop that is not properly guarded against reading past the
end of the string (see attached diff). In this case, len is 1 when the
loop is entered once more, but then pnt[2] is invalid and just happens
to be zero, leading to an invinite loop.

Unless I have misinterpreted the valgrind output "Address 0x415545D9 is
1 bytes after a block of size 164", the string that is parsed is this:

(gdb) x/166cb 0x415545D9-165
0x41554534:     82 'R'  82 'R'  5 '\005'        1 '\001'        -119
'\211'     78 'N'  77 'M'  -126 '\202'
0x4155453c:     1 '\001'        0 '\0'  49 '1'  50 '2'  51 '3'  52 '4' 
53 '5'  54 '6'
0x41554544:     55 '7'  56 '8'  57 '9'  48 '0'  49 '1'  50 '2'  51 '3' 
52 '4'
0x4155454c:     53 '5'  54 '6'  55 '7'  56 '8'  57 '9'  48 '0'  49 '1' 
50 '2'
0x41554554:     51 '3'  52 '4'  53 '5'  54 '6'  55 '7'  56 '8'  57 '9' 
48 '0'
0x4155455c:     49 '1'  50 '2'  51 '3'  52 '4'  53 '5'  54 '6'  55 '7' 
56 '8'
0x41554564:     57 '9'  48 '0'  49 '1'  50 '2'  51 '3'  52 '4'  53 '5' 
54 '6'
0x4155456c:     55 '7'  56 '8'  57 '9'  48 '0'  49 '1'  50 '2'  51 '3' 
52 '4'
0x41554574:     53 '5'  54 '6'  55 '7'  56 '8'  57 '9'  48 '0'  49 '1' 
50 '2'
0x4155457c:     51 '3'  52 '4'  53 '5'  54 '6'  55 '7'  56 '8'  57 '9' 
48 '0'
0x41554584:     49 '1'  50 '2'  51 '3'  52 '4'  53 '5'  54 '6'  55 '7' 
56 '8'
0x4155458c:     57 '9'  48 '0'  49 '1'  50 '2'  51 '3'  52 '4'  53 '5' 
54 '6'
0x41554594:     55 '7'  56 '8'  57 '9'  48 '0'  49 '1'  50 '2'  51 '3' 
52 '4'
0x4155459c:     53 '5'  54 '6'  55 '7'  56 '8'  57 '9'  48 '0'  49 '1' 
50 '2'
0x415545a4:     51 '3'  52 '4'  53 '5'  54 '6'  55 '7'  56 '8'  57 '9' 
48 '0'
0x415545ac:     49 '1'  50 '2'  51 '3'  52 '4'  53 '5'  54 '6'  55 '7' 
56 '8'
0x415545b4:     57 '9'  48 '0'  49 '1'  50 '2'  51 '3'  52 '4'  53 '5' 
67 'C'
0x415545bc:     69 'E'  28 '\034'       1 '\001'        25 '\031'      
0 '\0'  0 '\0'  0 '\0'  0 '\0'
0x415545c4:     0 '\0'  0 '\0'  25 '\031'       0 '\0'  0 '\0'  0 '\0' 
0 '\0'  0 '\0'
0x415545cc:     0 '\0'  0 '\0'  0 '\0'  62 '>'  0 '\0'  0 '\0'  0 '\0' 
0 '\0'
0x415545d4:     0 '\0'  0 '\0'  62 '>'  0 '\0'  0 '\0'  0 '\0'

Question to someone with more knowledge about ISO9660/RR: is mkisofs
generating an invalid image when invoked as described above, or
is the ISO parsing code insufficient? In the later case the attached
diff should be sufficient to fix the problem.

The patch follows the example given at another place where parse_xa() is
also called, but then followed by a while loop that tests against 3.
It looks like a sane value because it is large enough to ensure that
at least two flag bytes and the length in pnt[2] are valid.

-- 
Bye, Patrick Ohly
--  
Patrick.Ohly@gmx.de
patrick@core.de (MakeCD related mails)
http://home.pages.de/~ohly/
http://makecd.core.de/ (MakeCD home page)



Reply to: