#69 next_extent_size: Process /usr/bin/mkudffs was killed SIGSEG

open
nobody
None
5
2011-03-24
2011-03-24
Honza Horak
No

This bug was originally reported in https://bugzilla.redhat.com/show_bug.cgi?id=685005

abrt version: 1.1.17
architecture: x86_64
Attached file: backtrace, 5760 bytes
cmdline: mkudffs --media-type=dvdram /dev/sr0
component: udftools
Attached file: coredump, 380928 bytes
crash_function: next_extent_size
executable: /usr/bin/mkudffs
kernel: 2.6.35.11-83.fc14.x86_64
package: udftools-1.0.0b3-12.fc14
rating: 4
reason: Process /usr/bin/mkudffs was killed by signal 11 (SIGSEGV)
release: Fedora release 14 (Laughlin)
time: 1300158914
uid: 500

How to reproduce
-----
1. I was using mkudffs --type=dvdram on a dvdram that I have trouble reading on
a dvd recorder

Discussion

  • Honza Horak
    Honza Horak
    2011-03-24

    backtrace

     
    Attachments
  • It crashes in extent.c:

    uint32_t next_extent_size(struct udf_extent *start_ext, enum udf_space_type type, uint32_t blocks, uint32_t offset)
    {
    uint32_t inc;
    start_ext = next_extent(start_ext, type);
    cont:
    while (start_ext != NULL && start_ext->blocks < blocks) <----- while terminates when start_ext == NULL
    start_ext = next_extent(start_ext->next, type);

    if (start_ext->start % offset) <----- here comes the NULL dereference
    ........

     
  • Honza Horak
    Honza Horak
    2012-01-27

    This is a suggested patch:

    diff -up udftools-1.0.0b3/libudffs/extent.c.extsize udftools-1.0.0b3/libudffs/extent.c
    --- udftools-1.0.0b3/libudffs/extent.c.extsize 2012-01-26 09:45:22.217856499 +0100
    +++ udftools-1.0.0b3/libudffs/extent.c 2012-01-26 09:45:43.142855067 +0100
    @@ -50,7 +50,7 @@ cont:
    while (start_ext != NULL && start_ext->blocks < blocks)
    start_ext = next_extent(start_ext->next, type);

    - if (start_ext->start % offset)
    + if (start_ext != NULL && start_ext->start % offset)
    {
    inc = offset - (start_ext->start % offset);
    if (start_ext->blocks - inc < blocks)
    @@ -62,7 +62,7 @@ cont:
    else
    inc = 0;

    - return start_ext->start + inc;
    + return start_ext ? start_ext->start + inc : NULL;
    }

    struct udf_extent *prev_extent(struct udf_extent *start_ext, enum udf_space_type type)
    @@ -81,7 +81,7 @@ cont:
    while (start_ext != NULL && start_ext->blocks < blocks)
    start_ext = prev_extent(start_ext->prev, type);

    - if ((start_ext->start + start_ext->blocks) % offset)
    + if (start_ext != NULL && (start_ext->start + start_ext->blocks) % offset)
    {
    dec = (start_ext->start + start_ext->blocks) % offset;
    if (start_ext->blocks - dec < blocks)
    @@ -93,7 +93,7 @@ cont:
    else
    dec = 0;

    - return start_ext->start + start_ext->blocks - dec - blocks;
    + return start_ext ? start_ext->start + start_ext->blocks - dec - blocks : NULL;
    }

    struct udf_extent *find_extent(struct udf_disc *disc, uint32_t start)