#451578 genisoimage segfaults when using -J

Package:
genisoimage
Source:
cdrkit
Description:
Creates ISO-9660 CD-ROM filesystem images
Submitter:
Ivan Shmakov
Date:
2013-10-16 20:54:56 UTC
Severity:
important
#451578#5
Date:
2007-11-17 06:13:54 UTC
From:
To:
	Does anyone know what's happening there?

$ gdb genisoimage
(gdb) set args -C 312032,365680 -M /dev/cdrom -v -v -print-size -JR -uid 0 -gid 0 -graft-points users/ivan/archives/=/.../users/ivan/archives/

	Nothing strange (AFAICT) in /.../users/ivan/archives/.  I may
	specify another directory and it will segfault, too.  The
	problem vanishes if I omit `-J'.

	I believe it's a long-standing bug.  (I've just get my hands on
	building a recent cdrkit with `noopt nostrip' to trace it.)

(gdb) r
Starting program: /usr/bin/genisoimage -C 312032,365680 -M /dev/cdrom -v -v -print-size -JR -uid 0 -gid 0 -graft-points users/ivan/archives/=/.../users/ivan/archives/
genisoimage 1.1.6 (Linux)
Rock Ridge signatures found
Scanning /.../users/ivan/archives/
...
Scanning /.../users/ivan/archives/mercurial/scheme48/scheme/vm/util
Warning: missing whole name for: 'rr_moved'
Using SCHEM000.I;1 for  /.../users/ivan/archives/mercurial/scheme48/.hg/data/alt/schemetoc-record.scm.i (schemetoc-features.scm.i)
...
Using PS_PL000.SCM;1 for  /.../users/ivan/archives/mercurial/scheme48/scheme/vm/ps-platform-64-packages.scm (ps-platform-32-packages.scm)

Program received signal SIGSEGV, Segmentation fault.
0x08061e3a in joliet_compare_paths (r=0x94689c8, l=0x94689cc)
    at /.../debuild/cdrkit-1.1.6-debian-1-debug-build/genisoimage/joliet.c:555
555	/.../debuild/cdrkit-1.1.6-debian-1-debug-build/genisoimage/joliet.c: No such file or directory.
	in /.../debuild/cdrkit-1.1.6-debian-1-debug-build/genisoimage/joliet.c
(gdb) directory /.../src/cdrkit-1.1.6-debian-1/genisoimage/
(gdb) list
550			return (1);
551
552		rparent = rr->parent->jpath_index;
553		lparent = ll->parent->jpath_index;
554		if (rr->parent == reloc_dir) {
555			rparent = rr->self->parent_rec->filedir->jpath_index;
556		}
557		if (ll->parent == reloc_dir) {
558			lparent = ll->self->parent_rec->filedir->jpath_index;
559		}
(gdb) bt
#0  0x08061e3a in joliet_compare_paths (r=0x94689c8, l=0x94689cc)
    at /var/home/ivan/exp/debuild/cdrkit-1.1.6-debian-1-debug-build/genisoimage/joliet.c:555
#1  0xb7ebf9b7 in bsearch () from /lib/tls/libc.so.6
#2  0xb7ebf921 in bsearch () from /lib/tls/libc.so.6
#3  0xb7ebf921 in bsearch () from /lib/tls/libc.so.6
#4  0xb7ebf921 in bsearch () from /lib/tls/libc.so.6
#5  0xb7ebf907 in bsearch () from /lib/tls/libc.so.6
#6  0xb7ebf921 in bsearch () from /lib/tls/libc.so.6
#7  0xb7ebf907 in bsearch () from /lib/tls/libc.so.6
#8  0xb7ebf907 in bsearch () from /lib/tls/libc.so.6
#9  0xb7ebf907 in bsearch () from /lib/tls/libc.so.6
#10 0xb7ebf921 in bsearch () from /lib/tls/libc.so.6
#11 0xb7ebf921 in bsearch () from /lib/tls/libc.so.6
#12 0xb7ebf907 in bsearch () from /lib/tls/libc.so.6
#13 0xb7ebfae7 in qsort () from /lib/tls/libc.so.6
#14 0x080621c2 in generate_joliet_path_tables ()
    at /var/home/ivan/exp/debuild/cdrkit-1.1.6-debian-1-debug-build/genisoimage/joliet.c:662
#15 0x08056138 in main (argc=15, argv=0xbf955cd4)
    at /var/home/ivan/exp/debuild/cdrkit-1.1.6-debian-1-debug-build/genisoimage/genisoimage.c:3559
(gdb) frame 14
#14 0x080621c2 in generate_joliet_path_tables ()
    at /var/home/ivan/exp/debuild/cdrkit-1.1.6-debian-1-debug-build/genisoimage/joliet.c:662
662			qsort(&jpathlist[1], next_jpath_index - 1, sizeof (struct directory *),
(gdb) list
657		build_jpathlist(root);
658
659		do {
660			fix = 0;
661	#ifdef	PROTOTYPES
662			qsort(&jpathlist[1], next_jpath_index - 1, sizeof (struct directory *),
663				(int (*) (const void *, const void *)) joliet_compare_paths);
664	#else
665			qsort(&jpathlist[1], next_jpath_index - 1, sizeof (struct directory *),
666				joliet_compare_paths);
(gdb) frame 15
#15 0x08056138 in main (argc=15, argv=0xbf955cd4)
    at /var/home/ivan/exp/debuild/cdrkit-1.1.6-debian-1-debug-build/genisoimage/genisoimage.c:3559
3559				(*opnt->of_generate) ();
(gdb) list
3554		 * - most will generate the data on the fly when we get to the write
3555		 * pass.
3556		 */
3557		for (opnt = out_list; opnt; opnt = opnt->of_next) {
3558			if (opnt->of_generate != NULL) {
3559				(*opnt->of_generate) ();
3560			}
3561		}
3562
3563		/*
(gdb)

#451578#10
Date:
2007-11-17 12:03:01 UTC
From:
To:
Many bugs in genisoimage have never been in mkisofs and many bugs that
appear as old bugs in genisoimage have been fixed in mkisofs long time ago.

I cannot reproduce your problem with mkisofs and I recommend you to just
switch to a recent maintained original from:

ftp://ftp.berlios.de/pub/cdrecord/alpha/

the latest versionis currently 2.01.01a36

Jörg

#451578#15
Date:
2007-11-17 16:06:13 UTC
From:
To:
#include <hallo.h>
* Joerg Schilling [Sat, Nov 17 2007, 01:03:01PM]:

Blah. If you tried to reproduce his problem than you got access to his
filesystem, right? Otherwise I have trouble believing that.

Eduard.

#451578#20
Date:
2007-11-18 12:09:38 UTC
From:
To:
 >> $ gdb genisoimage
 >> (gdb) set args -C 312032,365680 -M /dev/cdrom -v -v -print-size -JR -uid 0 -gid 0 -graft-points users/ivan/archives/=/.../users/ivan/archives/

 >> Nothing strange (AFAICT) in /.../users/ivan/archives/.  I may
 >> specify another directory and it will segfault, too.  The problem
 >> vanishes if I omit `-J'.

 >> I believe it's a long-standing bug.  (I've just get my hands on
 >> building a recent cdrkit with `noopt nostrip' to trace it.)

 > Many bugs in genisoimage have never been in mkisofs and many bugs
 > that appear as old bugs in genisoimage have been fixed in mkisofs
 > long time ago.

 > I cannot reproduce your problem with mkisofs

	I could hardly believe that you have access to the very exact
	ISO-9660 which I've tried to merge (check -M, -C options above.)

	Although, if you have some spare bandwidth to waste, I could put
	the image on the web (approximately 700 MiB; nothing to be kept
	secret -- just some free software packages.)

[...]

#451578#25
Date:
2007-11-18 12:10:24 UTC
From:
To:
	Looks like there're issues with merging a previous session in.

	Both joliet_compare_paths () and generate_joliet_path_tables ()
	assume that whenever `DIRENTRY->parent == reloc_dir',
	`DIRENTRY->self->parent_rec' will be non-NULL.

	This is the case when DIRENTRY originates from
	`insert_file_entry ()'.  However, somehow it gets wrong when
	it's `match_cl_re_entries ()' to set `parent_rec'.  It appears
	that there're no corresponding entries in `cl_dirs' for some of
	the `re_dirs' entries!  (NB: even if it's the previous session
	that was messed up, and it probably was, it's still undesirable
	to segfault in this case.)

	I've slightly modified the source, mainly to produce some
	warnings related to the case.  Here's how it runs now:

$ genisoimage \
      -input-charset iso-8859-1 \
      -C 312032,365680 -M /dev/cdrom -v -v -print-size \
      -JR -uid 0 -gid 0 \
      -graft-points users/ivan/archives/=/.../users/ivan/archives/
...
Warning: missing whole name for: 'rr_moved'
Warning: re [0x8d514a8]->de [0x84d1178]->parent_rec = 0
Warning: re [0x8d514a8]->de [0x84d1178]->whole_name = "rr_moved/remotes"
Warning: re [0x8ce1170]->de [0x84c9e58]->parent_rec = 0
Warning: re [0x8ce1170]->de [0x84c9e58]->whole_name = "rr_moved/origin"
Warning: re [0x8c626a8]->de [0x84c5838]->parent_rec = 0
Warning: re [0x8c626a8]->de [0x84c5838]->whole_name = "rr_moved/heads"
Using SCHEM000.I;1 for  /mnt/users/ivan/archives/mercurial/scheme48/.hg/data/alt/schemetoc-record.scm.i (schemetoc-features.scm.i)
...
Warning: rr [0x8c62058]->self [0x84c5838] (w/name = rr_moved/heads) RR_MOVED?
Warning: ll [0x8c62058]->self [0x84c5838] (w/name = rr_moved/heads) RR_MOVED?
... a number of these...
Warning: rr [0x8cdffa8]->self [0x84c9e58] (w/name = rr_moved/origin) RR_MOVED?
Warning: ll [0x8cdffa8]->self [0x84c9e58] (w/name = rr_moved/origin) RR_MOVED?
... and of these as well...
Warning: rr [0x8d50e78]->self [0x84d1178] (w/name = rr_moved/remotes) RR_MOVED?
Warning: rr [0x8d50e78]->self [0x84d1178] (w/name = rr_moved/remotes) RR_MOVED?
... intermingled with these, too... qsort () does its work, doesn't it?..
Warning: dpnt [0x8c62058]->self [0x84c5838 (w/name = rr_moved/heads) RR_MOVED?
Warning: dpnt [0x8cdffa8]->self [0x84c9e58 (w/name = rr_moved/origin) RR_MOVED?
Warning: dpnt [0x8d50e78]->self [0x84d1178 (w/name = rr_moved/remotes) RR_MOVED?
...
Total extents scheduled to be written = 22503
22503
$

	The diff follows.
--- cdrkit-1.1.6-debian-1/genisoimage/genisoimage.c 2007-03-17 17:59:16.000000000 +0600 +++ cdrkit-1.1.6-debian-1-my/genisoimage/genisoimage.c 2007-11-18 17:01:33.000000000 +0600 @@ -3307,6 +3307,8 @@ * finish_cl_pl_entries can do its job */ match_cl_re_entries(); + + check_re_entries (); } #ifdef APPLE_HYB /* free up any HFS filename mapping memory */ --- cdrkit-1.1.6-debian-1/genisoimage/joliet.c 2007-03-15 03:14:33.000000000 +0600 +++ cdrkit-1.1.6-debian-1-my/genisoimage/joliet.c 2007-11-18 16:22:27.000000000 +0600 @@ -551,10 +551,28 @@ rparent = rr->parent->jpath_index; lparent = ll->parent->jpath_index; - if (rr->parent == reloc_dir) { + if (rr->parent != reloc_dir) { + /* do nothing */ + } else if (rr->self->parent_rec == 0) { + /* issue a warning */ + fprintf (stderr, + ("Warning: rr [%p]->self [%p]" + " (w/name = %s) RR_MOVED?\n"), + rr, rr->self, rr->self->whole_name); + } else { + /* redirect to a non-RR_MOVED directory */ rparent = rr->self->parent_rec->filedir->jpath_index; } - if (ll->parent == reloc_dir) { + if (ll->parent != reloc_dir) { + /* do nothing */ + } else if (ll->self->parent_rec == 0) { + /* issue a warning */ + fprintf (stderr, + ("Warning: ll [%p]->self [%p]" + " (w/name = %s) RR_MOVED?\n"), + ll, ll->self, ll->self->whole_name); + } else { + /* redirect to a non-RR_MOVED directory */ lparent = ll->self->parent_rec->filedir->jpath_index; } if (rparent < lparent) { @@ -739,6 +757,13 @@ dpnt->parent->jpath_index); set_722(jpath_table_m + jpath_table_index, dpnt->parent->jpath_index); + } else if (dpnt->self->parent_rec == 0) { + /* issue a warning */ + fprintf (stderr, + ("Warning: dpnt [%p]->self [%p" + " (w/name = %s) RR_MOVED?\n"), + dpnt, dpnt->self, + dpnt->self->whole_name); } else { set_721(jpath_table_l + jpath_table_index, dpnt->self->parent_rec->filedir->jpath_index); --- cdrkit-1.1.6-debian-1/genisoimage/multi.c 2007-03-15 03:14:33.000000000 +0600 +++ cdrkit-1.1.6-debian-1-my/genisoimage/multi.c 2007-11-18 17:13:01.000000000 +0600 @@ -1837,6 +1837,27 @@ } void +check_re_entries (void) +{ + struct dir_extent_link *re; + + /* for each relocated directory */ + for (re = re_dirs; re != 0; re = re->next) { + if (re->de == 0) { + /* it's okay, check match_cl_re_entries () */ + } else if (re->de->parent_rec == 0) { + fprintf (stderr, + ("Warning: re [%p]->de [%p]" + "->parent_rec = 0\n" + "Warning: re [%p]->de [%p]" + "->whole_name = \"%s\"\n"), + re, re->de, + re, re->de, re->de->whole_name); + } + } +} + +void finish_cl_pl_for_prev_session() { struct dir_extent_link *re = re_dirs;
#451578#30
Date:
2007-11-18 12:09:11 UTC
From:
To:
 >> I cannot reproduce your problem with mkisofs and I recommend you to
 >> just switch to a recent maintained original from:

 > Blah. If you tried to reproduce his problem than you got access to
 > his filesystem, right? Otherwise I have trouble believing that.

	Indeed, genisoimage segfaults only when there's a previous
	session to be merged, and only for some specific sessions.