Gabriel - Thanks for reporting the problem and trying to push Debian
forward.  I don't know what's wrong, but I will try to investigate when I
get a chance.

On Mon, Mar 24, 2025 at 8:48 AM Gabriel F. T. Gomes <
gabr...@inconstante.net.br> wrote:

> Dear Libcdio developers,
>
> I need your help with the recent ABI changes in libiso9660.
>
> The 2.2.0 release contains the ABI bump for libiso9660 due to the
> addition of new fields/members in a few structs. I understand that
> previous versions (also recently released) did not have the bump which
> was rectified with version 2.2.0. All is well with regards to this.
>
> However, while working on the Debian update for the sub-libraries in
> the parent libcdio project, I got a few Segmentation Faults in the
> 32-bits architectures. I tried to dig as deep as I could, and even
> though I have not yet precisely traced the events that cause the issue,
> I have a guess.
>
> I have only a couple of question (lines prefixed with '*'), even though
> the email is huge (sorry about that - I'm bad at writing).
>
> Let me first explain what is the condition and you can maybe stop me
> right there in case you think I'm doing something wrong.
>
> Mixing old and new sub-libraries
> --------------------------------
>
> The libcdio project produces several sub-libraries, including
> libcdio.so and libiso9660.so, in version 2.1.0, these would be their
> filanames (and SONAMEs) in the filesystem:
>
>   libcdio.so.19.0.0
>   libiso9660.so.11.0.0
>
> Whereas in version 2.2.0, they would be:
>
>   libcdio.so.19.0.0
>   libiso9660.so.12.0.0
>
> In Debian (and probably likewise in other distros), it is possible to
> install both versions of libiso9960 concurrently. This is useful when
> you have applications that you don't want to recompile, so you keep
> distributing the old library for users who have applications that
> linked against libiso9660.so.11.
>
> However, only a single version of libcdio can be installed.
>
> In Debian, one could install libiso9660.so.11 (from libcdio 2.1.0),
> libiso9660.so.12 (from libcdio 2.2.0), and libcdio.so.19 (from libcdio
> 2.2.0).
>
> And an application that linked against libiso9660.so.11 (and
> libcdio.so.19) will use sub-libraries from different versions of the
> libcdio project. And this is what causes the Segmentation Fault.
>
> * Should Debian stop right there and never allow this mismatching?
>
> What does the error look like
> -----------------------------
>
> In GDB, it looks like this:
>
> Program received signal SIGSEGV, Segmentation fault.
> 0xf7ec983c in ?? () from /lib/i386-linux-gnu/libc.so.6
> (gdb) bt
> #0  0xf7ec983c in ?? () from /lib/i386-linux-gnu/libc.so.6
> #1  0xf7f87c43 in iso9660_fs_read_pvd (p_cdio=0x5655a1c0, p_pvd=0xf7f96c22
> <cdio_generic_free+3>) at iso9660_fs.c:635
> #2  0xf7f87cce in iso9660_fs_read_superblock (p_cdio=0x5655a1c0,
> iso_extension_mask=255 '\377') at iso9660_fs.c:659
> #3  0xf7f8858e in _fs_stat_root (p_cdio=0x5655a1c0) at iso9660_fs.c:958
> #4  0xf7f88fc1 in iso9660_fs_stat (p_cdio=0x5655a1c0, psz_path=0xf7f8c9f3
> "/") at iso9660_fs.c:1227
> #5  0xf7f891fa in iso9660_fs_readdir (p_cdio=0x5655a1c0,
> psz_path=0xf7f8c9f3 "/") at iso9660_fs.c:1364
> #6  0xf7f896ea in find_lsn_recurse (p_image=0x5655a1c0,
> iso9660_readdir=0xf7f891ae <iso9660_fs_readdir>, psz_path=0xf7f8c9f3 "/",
> lsn=26, ppsz_full_filename=0xffffd508) at iso9660_fs.c:1520
> #7  0xf7f89a61 in iso9660_find_fs_lsn (p_cdio=0x5655a1c0, i_lsn=26) at
> iso9660_fs.c:1603
> #8  0x56556211 in main () at rep.c:18
>
> (the reproducer is further down this message)
>
> Changes to the opaque CdIo_t (aka struct _CdIo)
> -----------------------------------------------
>
> The CdIo_t type, which is returned by functions like cdio_open, is an
> opaque type, as mentioned in the public header (cdio/cdio.h):
>
>   /** This is an opaque structure for the CD object. */
>   typedef struct _CdIo CdIo_t;
>
> However, libiso9960 knows about its internal details, and access
> fields/member directly, such as in iso9660_fs_read_superblock:
>
>   bool
>   iso9660_fs_read_superblock (CdIo_t *p_cdio,
>                               iso_extension_mask_t iso_extension_mask)
>   {
>     if (!p_cdio) return false;
>     generic_img_private_t *p_env = (generic_img_private_t *) p_cdio->env;
>                                                              ~~~~~~~~~~~
>                                           Direct access here ^
>
> However, struct _CdIo changed between versions 2.1.0 and 2.2.0. More
> specifically, it change with commit ID e35135114e71 and now has the
> additional member/field `cdio_header_t header'. This changes the size
> of `struct _CdIo' and likely the offsets of the fields.
>
> My guess is that this is what's causing the segfaults.
>
> While I understand that CdIo_t is a private type, it is only private
> with regards to the libcdio project. One could say that Libiso9960 made
> it public by accessing fields directly. If so, libcdio needs a SONAME
> bump. Conversely, one would say that libiso9660 is currently making
> invalid access and should be fixed and should use accessor methods
> instead.
>
> * Do you have an opinion on this?
>
> Reproducer
> ----------
>
> I'm cheating here, because I'm reusing the CUE/BIN pair from the test
> suite in libdevice-cdio-perl. Anyhow, to remove this Perl package from
> the equation, the following program could be used:
>
>   #include <err.h>
>   #include <stdio.h>
>   #include <stdlib.h>
>   #include <sys/types.h>
>   #include <cdio/cdio.h>
>   #include <cdio/iso9660.h>
>   int
>   main(void)
>   {
>     CdIo_t *cdio;
>     iso9660_stat_t *stat;
>     cdio = cdio_open("isofs-m1.cue", DRIVER_UNKNOWN);
>     if (cdio == NULL)
>       err(EXIT_FAILURE, "unable to open disk file");
>     stat = iso9660_fs_find_lsn(cdio, 26);
>     if (stat == NULL)
>       err(EXIT_FAILURE, "unable to find LSN");
>     cdio_destroy(cdio);
>     return 0;
>   }
>
> The data files (isofs-m1.cue and isofs-m1.bin) can be found in
> libdevice-cdio-perl, e.g.:
>
>   https://sources.debian.org/src/libdevice-cdio-perl/2.0.0-2/data/
>
> You must build this against libis9660.so.11 (from libcdio 2.1.0), but
> update libcdio.so.19 (to libcdio 2.2.0)
>
> The segmentation fault only happens in 32-bits architectures, and I
> still can't explain why.
>
> Debian specifics
> ----------------
>
> In the interest of being totally upfront, I should also mention that
> Debian carries a patch for the lseek/fseeko issues in 32-bits
> architectures.
>
> Since these functions deal file access, I simply assumed that this
> patch should not cause this Segmentation Fault, anyhow, the patch is as
> follows:
>
> --- libcdio.orig/lib/driver/_cdio_stdio.h
> +++ libcdio/lib/driver/_cdio_stdio.h
> @@ -22,6 +22,12 @@
>
>  #include "_cdio_stream.h"
>
> +#include <features.h>
> +#if defined(_FILE_OFFSET_BITS) && defined(__REDIRECT) &&
> (_FILE_OFFSET_BITS == 64)
> +#define lseek64 lseek
> +#define fseeko64 fseeko
> +#endif
> +
>  /*!
>    Initialize a new stdio stream reading from pathname.
>    A pointer to the stream is returned or NULL if there was an error.
>
>
> (reference:
> https://sources.debian.org/src/libcdio/2.2.0-2/debian/patches/arm-t64-redirect-fix.patch/
> )
>
>
> Cheers,
> Gabriel
>
>
> PS: The Debian issue is being tracked here:
> https://bugs.debian.org/1094736
>
>

Reply via email to