Bug 1913465

Summary: createrepo_c segfault when attempting to print PrimaryXmlFile or PrimarySqlite object after closing
Product: Red Hat Enterprise Linux 8 Reporter: Ryan Mullett <rmullett>
Component: createrepo_cAssignee: amatej
Status: CLOSED ERRATA QA Contact: Jan Blazek <jblazek>
Severity: low Docs Contact:
Priority: low    
Version: 8.3CC: amatej, fhirtz, pkratoch
Target Milestone: rcKeywords: Triaged
Target Release: 8.0Flags: pm-rhel: mirror+
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: createrepo_c-0.17.2-1.el8 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2021-11-09 18:06:40 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1951406    
Bug Blocks:    
Attachments:
Description Flags
segfault from RHEL 8 test system illustrating the issue none

Description Ryan Mullett 2021-01-06 20:30:00 UTC
Created attachment 1745041 [details]
segfault from RHEL 8 test system illustrating the issue

Description of problem:
After calling the .close() method on a PrimaryXmlFile or PrimarySqlite object, calling __repr__ or __str__ results in a coredump

Version-Release number of selected component (if applicable):
createrepo_c-libs-0.15.11-2.el8.x86_64
python3-createrepo_c-0.15.11-2.el8.x86_64

Issue appears to be present in every release across 7 and 8.

How reproducible:
Always

Steps to Reproduce:
Example 1:
# python3 -c 'import createrepo_c; p = createrepo_c.PrimarySqlite("primary.sqlite"); p.close(); p.__str__()'
Segmentation fault (core dumped)

Example 2:
# python3 -c 'import createrepo_c; p = createrepo_c.PrimarySqlite("primary.sqlite"); p.close(); p.__repr__()'
Segmentation fault (core dumped)

Example 3:
# python3 -c 'import createrepo_c; p = createrepo_c.PrimaryXmlFile("primary.xml"); p.close(); p.__str__()'
Segmentation fault (core dumped)

Example 4:
# python3 -c 'import createrepo_c; p = createrepo_c.PrimaryXmlFile("primary.xml"); p.close(); p.__repr__()'
Segmentation fault (core dumped)

Actual results:
Segfault

Expected results:
After closing, the object should still be available to be read, as is standard for other python modules. For example:

# python -c 'p = open("items.xml"); p.close(); print(p.__str__())'
<_io.TextIOWrapper name='items.xml' mode='r' encoding='UTF-8'>

Additional info:
Looking around it appears that other methods that are fully implemented via this library go through a check to see if the object was already closed. They go through check_XmlFileStatus():

static int
check_XmlFileStatus(const _XmlFileObject *self)
{
    assert(self != NULL);
    assert(XmlFileObject_Check(self));
    if (self->xmlfile == NULL) {
        PyErr_SetString(CrErr_Exception,
            "Improper createrepo_c XmlFile object (Already closed file?).");
        return -1;
    }
    return 0;
}

However, the __repr__ and __str__ do not. This results in a segfault when they try to access the object which is NULL after having been closed.

Comment 1 Ryan Mullett 2021-01-06 20:34:06 UTC
One additional check that was performed, which I neglected to add to initial description is below. This is simply to illustrate that the issue is not the check_XmlFileStatus(). That function is working correctly for other functions which do call it:

# python3 -c 'import createrepo_c; p = createrepo_c.PrimaryXmlFile("backup-primary.xml"); p.close(); p.set_num_of_pkgs(5)'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
createrepo_c.CreaterepoCError: Improper createrepo_c XmlFile object (Already closed file?).

Comment 4 amatej 2021-03-29 14:08:57 UTC
The previous PR was fixing just xmlfile I have made another one which also fixes sqlite and it prints the representation of a closed xmlfile/sqlite instead of throwing an exception.

In addition it adds unit test testing.

https://github.com/rpm-software-management/createrepo_c/pull/257

Comment 22 errata-xmlrpc 2021-11-09 18:06:40 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (createrepo_c bug fix and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2021:4197