Bug 2120926 - SIGSEGV if pathname is invalid MBS, despite valid UTF-8
Summary: SIGSEGV if pathname is invalid MBS, despite valid UTF-8
Keywords:
Status: CLOSED EOL
Alias: None
Product: Fedora
Classification: Fedora
Component: unrar-free
Version: 36
Hardware: x86_64
OS: Linux
unspecified
unspecified
Target Milestone: ---
Assignee: Davide Cavalca
QA Contact:
URL:
Whiteboard:
Depends On: 2136961
Blocks:
TreeView+ depends on / blocked
 
Reported: 2022-08-24 03:41 UTC by John Reiser
Modified: 2023-05-25 15:51 UTC (History)
1 user (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2023-05-25 15:51:32 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
Debugging session showing error 84, traceback, and various interesting values (9.70 KB, text/plain)
2022-08-24 03:41 UTC, John Reiser
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Gitlab bgermann unrar-free issues 2 0 None opened SIGSEGV if pathname is invalid MBS, despite valid UTF-8 2022-08-24 18:42:52 UTC

Description John Reiser 2022-08-24 03:41:40 UTC
Created attachment 1907309 [details]
Debugging session showing error 84, traceback, and various interesting values

Description of problem: If a pathname contained within a .rar archive is invalid when interpreted as MBS or WCS (Multi-Byte String or Wide Character String) but is valid when interpreted as UTF-8, then unrar gets a SIGSEGV because it gives up when (errno == 84), namely "Invalid or incomplete multibyte or wide character".  Instead, the archive_entry_pathname() routine should recognize (errno == 84) from archive_mstring_get_mbs(), then try the UTF-8 version before giving up and returning 0 (nullptr).  Also, the immediate cause of the SIGSEGV is passing nullptr to strdup(), so the code should implement a new subroutine unrar_strdup() which avoids SIGSEGV by checking first for nullptr argument.


Version-Release number of selected component (if applicable):
unrar-0.1.1-1.fc36.x86_64


How reproducible: Every time


Steps to Reproduce:
1. unrar --list Drive_BT+WIFI.rar  # vendor-supplied (Realtek) file of device driver for Windows
2.
3.

Actual results: SIGSEGV


Expected results: no SIGSEGV


Additional info:
See attached gdb debugging session.  Unfortunately the original input is 184MB, so I cannot attach that.

Comment 1 Davide Cavalca 2022-08-24 18:42:53 UTC
I'm fairly sure this is an upstream issue so I've filed https://gitlab.com/bgermann/unrar-free/-/issues/2

Any chance the original file you used to repro this can be downloaded from somewhere?

Comment 2 John Reiser 2022-08-24 21:28:34 UTC
After searching the 'net for more than 45 minutes, I could not find the file.
So I uploaded it; access via "wget http://www.bitwagon.com/Drive_BT+WIFI.rar"
(192,364,641 bytes), which will reside (un-indexed) for some days.

Comment 3 John Reiser 2022-08-25 18:55:29 UTC
The problem actually lies in libarchive/archive_entry.c because it assumes Windows
using MBS (Multi-Byte String; actually UCS-16), whereas Linux uses UTF-8:
-----
archive_entry_pathname(struct archive_entry *entry)
{
    const char *p;
    if (archive_mstring_get_mbs(
        entry->archive, &entry->ae_pathname, &p) == 0)
        return (p);
    if (errno == ENOMEM)
        __archive_errx(1, "No memory");
    return (NULL);
}
-----
So the quick-and-dirty fix for Linux is to call archive_entry_pathname_utf8
(which is the very next routine in the source file) instead of archive_mstring_get_mbs.

The more general fix is to try harder in every environment.  In particular
check for (errno == EILSEQ) [from /usr/include/asm-generic/errno.h].
If EILSEQ for one encoding, then try the next encoding.
(And on Linuux, try UTF-8 first.)

Comment 4 John Reiser 2022-08-25 19:03:07 UTC
Also, defend against strdup(0):
-----
char *
my_strdup(char const *ptr)
{
  if (ptr)
    return strdup(ptr);
  {
    char temp[24];
    static unsigned counter = 0;
    sprintf(temp, "BadPath-%d", ++counter);
    return strdup(temp);
  }
}
-----

Comment 5 John Reiser 2022-08-26 16:41:37 UTC
Fix posted to https://github.com/libarchive/libarchive/issues/1769 .

Comment 6 Ben Cotton 2023-04-25 17:49:08 UTC
This message is a reminder that Fedora Linux 36 is nearing its end of life.
Fedora will stop maintaining and issuing updates for Fedora Linux 36 on 2023-05-16.
It is Fedora's policy to close all bug reports from releases that are no longer
maintained. At that time this bug will be closed as EOL if it remains open with a
'version' of '36'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, change the 'version' 
to a later Fedora Linux version. Note that the version field may be hidden.
Click the "Show advanced fields" button if you do not see it.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora Linux 36 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora Linux, you are encouraged to change the 'version' to a later version
prior to this bug being closed.

Comment 7 Ludek Smid 2023-05-25 15:51:32 UTC
Fedora Linux 36 entered end-of-life (EOL) status on 2023-05-16.

Fedora Linux 36 is no longer maintained, which means that it
will not receive any further security or bug fix updates. As a result we
are closing this bug.

If you can reproduce this bug against a currently maintained version of Fedora Linux
please feel free to reopen this bug against that version. Note that the version
field may be hidden. Click the "Show advanced fields" button if you do not see
the version field.

If you are unable to reopen this bug, please file a new report against an
active release.

Thank you for reporting this bug and we are sorry it could not be fixed.


Note You need to log in before you can comment on or make changes to this bug.