Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[XERCESC-2188] Fix potential double-free in usage of ReaderMgr::pushReader() #47

Closed
wants to merge 1 commit into from

Conversation

rouault
Copy link
Contributor

@rouault rouault commented Jan 23, 2022

The fix consists in adding a new argument to pushReader() to specify if
ReaderMgr must own the passed entity, and adapt callers to specify the
right value of this ownership flag depending on the calling context.

SPDX-FileCopyrightText: Portions Copyright 2021 Siemens
Modified on 15-Jul-2021 by Siemens and/or its affiliates to fix CVE-2018-1311: Apache Xerces-C use-after-free vulnerability scanning external DTD. Copyright 2021 Siemens.

Co-authored-by: Even Rouault [email protected]

Supersedes #46 (avoids the memory leak in the unit tests)
@johnjamesmccann Do you have access to a reproducer to confirm it fixes the issue ? I couldn't easily find a reproducer

The fix consists in adding a new argument to pushReader() to specify if
ReaderMgr must own the passed entity, and adapt callers to specify the
right value of this ownership flag depending on the calling context.

SPDX-FileCopyrightText: Portions Copyright 2021 Siemens
Modified on 15-Jul-2021 by Siemens and/or its affiliates to fix CVE-2018-1311: Apache Xerces-C use-after-free vulnerability scanning external DTD. Copyright 2021 Siemens.

Co-authored-by: Even Rouault <[email protected]>
@johnjamesmccann
Copy link

johnjamesmccann commented Jan 25, 2022 via email

@rouault
Copy link
Contributor Author

rouault commented Jan 25, 2022

I cant see how my changes could cause a test regression, all my change does is delete 4 smart pointers that are not used in the code base.

yes, but that causes a memory leak since nobody would take care of freeing the declDTD object. Hence my extra changes

@johnjamesmccann
Copy link

johnjamesmccann commented Feb 1, 2022 via email

@rouault
Copy link
Contributor Author

rouault commented Feb 1, 2022

or has it been added in your fork which is later than mine?

yes

@johnjamesmccann
Copy link

johnjamesmccann commented Feb 1, 2022 via email

@rouault
Copy link
Contributor Author

rouault commented Feb 1, 2022

So just to confirm there is nothing you need me to do to get this fix in the code base?

no, we just need someone with commit rights in this repository to review & merge it

@theta682
Copy link

theta682 commented Feb 1, 2022

@rleigh-codelibre can you merge this PR and make a new release?

@theta682
Copy link

theta682 commented Feb 1, 2022

@scantor this vulnerability was reported almost 4 years ago. It has to be finally fixed.

@scantor
Copy link
Contributor

scantor commented Feb 2, 2022

Since you addressed me personally, I can simply reiterate as I have in Jira (which is where this proposal should be, this is not a GitHub project) that I don't have any exposure to, and thus no source of resources with which to work on, anything in the DTD code unless it's a trivial fix that doesn't change the ABI and I'm already doing some other work on the code.

Nothing else has arisen with the code that necessitated a release for my project, so there hasn't been any opportunity for me to look at anything else.

I am not stopping anybody else from doing the work, and nobody is stopping others from joining the project as committers, which is certainly needed for obvious reasons.

One issue that's perhaps less obvious is that a fix that requires a 4.0 rev may not get uptake by the few distributors of the current version. I imagine that's why Red Hat took the approach they took with it and just made it leak memory instead. Perhaps that's the best option in the end after all. I really have not looked at the issue at all in any depth to understand the trade-offs or possible fixes.

@rleigh-codelibre
Copy link
Contributor

I am not sufficiently familiar with this part of the codebase to review it meaningfully, but the changes look good and the unit tests are passing and not reporting any leaks, so I think merging this should be fairly risk-free.

Regarding making a new release, all of the recent bugfixes will need backporting to the 3.2 branch if we want to have a new 3.2 point release with all of these changes included. There are quite a few to backport thanks to all the work done recently, primarily by @rouault. @scantor Would you be able to make the release? I can probably find some time to do the backporting, unless you want to do this.

@scantor
Copy link
Contributor

scantor commented Feb 2, 2022

I looked at the fix last night at least in cursory fashion. It can't be backported to 3.2 because it's an API and therefore ABI change. Given some method defaulting it could probably be a 3.3 since it would be backwardly-compatible.

As with you, I have absolutely no idea if the fix is either sufficient or doesn't break anything. I don't really care for my own purposes so would defer to others on whether to accept the patch given that lack of insight into its correctness.

As for doing a release, not really, no. It would be very unlikely for me to find any time to do so until some time later this year, possibly in the Spring. And I can't promise that.

@johnjamesmccann
Copy link

Hello Scott Cantor,

Did this hot fix make it into the xerces code base? I think previously you alluded to the possibility of having this in the code base for a release in spring this year (although you never committed to that)?

Did that happen or is this PR still in the review stage?

Thanks and kind regards

John

@scantor
Copy link
Contributor

scantor commented May 17, 2022

No, and no, I have no expectation of any releases. If a security issue that actually affects my code comes up I would probably apply this and bump to 3.3. This cannot be part of a patch to 3.2, as I said.

This project needs active committers that have the time allocated to work on it. Until it gets some, it's going to stay moribund. If you need this fix, I would definitely suggest that you consider becoming one or find somebody else who is able to. If that happens, I am willing to help that person or persons get through the release process.

fCurReader = fReaderStack->pop();
fCurEntity = fEntityStack->pop();

popReaderAndEntity();
Copy link

@labossip labossip Jun 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The call to popReaderAndEntity may delete fCurEntity. This will result in the deleted pointer being passed to the EndOfEntityException through prevEntity resulting in potential issues when this pointer is dereferenced in the code that handles the exception.

@johnjamesmccann
Copy link

Hello Rouault,

Has this fix made its way into the xerces code base?

Kind regards

John

@scantor
Copy link
Contributor

scantor commented Aug 22, 2023

It has not, and I don't think it's even known that the fix is correct.

@johnjamesmccann
Copy link

Thanks for your response Scott,

How does it get to be known that the "fix is correct."? It appears that the tests are passing and there are no regressions. This hotfix is really important for one of our customers, so we would like to work with you to get it into the codebase.

Looking forward to your response

John

@scantor
Copy link
Contributor

scantor commented Aug 22, 2023

There are nowhere near adequate tests to treat that as meaningful, it's merely a data point. It's known when somebody who knows the code reviews the change for correctness. There are no active committers left who know the code, QED.

There's a comment above that makes a case that this fix introduces a bug, i.e. a regression. Maybe it does, maybe it doesn't. That's plenty good enough for me to treat it as suspect.

As for your customer, if you need the project to be viable, then you need to provide ongoing committers to make it viable.

@johnjamesmccann
Copy link

Apache-496067-disclosure-report.pdf

Hello Scott here is the vulnerability report as reported by the UK National Cyber Security Center, which outlines the vulnerability and even mentions the problematic lines which are part of the #47 thread

I have noted that @rleigh-codelibre comment on Feb 2, 2022 which states "the changes look good and the unit tests are passing and not reporting any leaks, so I think merging this should be fairly risk-free."

I will consider becoming a committer to this project to fix this vulnerability

Kind regards

John

@scantor
Copy link
Contributor

scantor commented Aug 22, 2023

I will consider becoming a committer to this project to fix this vulnerability

Only if you're in it for the long haul, it's a commitment (pun intended) to actually sustain the code base, not just a means of getting one fix applied.

@boris-kolpackov
Copy link
Contributor

FYI: #54

@boris-kolpackov
Copy link
Contributor

PR #54 has been merged:

master: b38ab79
xerces-3.2: e002426

So I am going to close this PR. Thanks for the idea of the fix, on which PR 54 is based!

raspbian-autopush pushed a commit to raspbian-packages/xerces-c that referenced this pull request Jan 4, 2024
These are the instructions for observing the bug (before this commit):

$ git clone https://github.com/apache/xerces-c.git
$ cd xerces-c
$ mkdir build
$ cd build
$ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug ..
$ make -j8
$ cp ../samples/data/personal.xml .

$ cat <<EOF >personal.dtd
<?xml encoding="ISO-8859-1"?>
<!ENTITY % nonExistentEntity SYSTEM "non-existent.ent">
%nonExistentEntity;
EOF

$ gdb samples/StdInParse
(gdb) b IGXMLScanner.cpp:1544
(gdb) run <personal.xml
1544	            fReaderMgr.pushReader(reader, declDTD);
(gdb) p declDTD
$1 = (xercesc_4_0::DTDEntityDecl *) 0x49ac68
(gdb) n
1547	            dtdScanner.scanExtSubsetDecl(false, true);
(gdb) n
1548	        }
(gdb) s
...
(gdb) s                     # The Janitor is about to delete the above declDTD.
90	        delete fData;
(gdb) p fData
$1 = (xercesc_4_0::DTDEntityDecl *) 0x49ac68
(gdb) b ReaderMgr.cpp:1024
(gdb) n
...
(gdb) n                     # Now we about to dereference the deleted declDTD.
1024	    if (curEntity && !curEntity->isExternal())
(gdb) p curEntity
$2 = (const xercesc_4_0::XMLEntityDecl *) 0x49ac68

Origin: apache/xerces-c@e002426
Bug: apache/xerces-c#47
Bug: apache/xerces-c#54
Bug: https://issues.apache.org/jira/browse/XERCESC-2188
Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2018-1311
Bug-Debian: https://bugs.debian.org/947431

Gbp-Pq: Name CVE-2018-1311.patch
raspbian-autopush pushed a commit to raspbian-packages/xerces-c that referenced this pull request Jan 4, 2024
These are the instructions for observing the bug (before this commit):

$ git clone https://github.com/apache/xerces-c.git
$ cd xerces-c
$ mkdir build
$ cd build
$ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug ..
$ make -j8
$ cp ../samples/data/personal.xml .

$ cat <<EOF >personal.dtd
<?xml encoding="ISO-8859-1"?>
<!ENTITY % nonExistentEntity SYSTEM "non-existent.ent">
%nonExistentEntity;
EOF

$ gdb samples/StdInParse
(gdb) b IGXMLScanner.cpp:1544
(gdb) run <personal.xml
1544	            fReaderMgr.pushReader(reader, declDTD);
(gdb) p declDTD
$1 = (xercesc_4_0::DTDEntityDecl *) 0x49ac68
(gdb) n
1547	            dtdScanner.scanExtSubsetDecl(false, true);
(gdb) n
1548	        }
(gdb) s
...
(gdb) s                     # The Janitor is about to delete the above declDTD.
90	        delete fData;
(gdb) p fData
$1 = (xercesc_4_0::DTDEntityDecl *) 0x49ac68
(gdb) b ReaderMgr.cpp:1024
(gdb) n
...
(gdb) n                     # Now we about to dereference the deleted declDTD.
1024	    if (curEntity && !curEntity->isExternal())
(gdb) p curEntity
$2 = (const xercesc_4_0::XMLEntityDecl *) 0x49ac68

Origin: apache/xerces-c@e002426
Bug: apache/xerces-c#47
Bug: apache/xerces-c#54
Bug: https://issues.apache.org/jira/browse/XERCESC-2188
Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2018-1311
Bug-Debian: https://bugs.debian.org/947431

Gbp-Pq: Name CVE-2018-1311.patch
raspbian-autopush pushed a commit to raspbian-packages/xerces-c that referenced this pull request Feb 15, 2024
These are the instructions for observing the bug (before this commit):

$ git clone https://github.com/apache/xerces-c.git
$ cd xerces-c
$ mkdir build
$ cd build
$ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug ..
$ make -j8
$ cp ../samples/data/personal.xml .

$ cat <<EOF >personal.dtd
<?xml encoding="ISO-8859-1"?>
<!ENTITY % nonExistentEntity SYSTEM "non-existent.ent">
%nonExistentEntity;
EOF

$ gdb samples/StdInParse
(gdb) b IGXMLScanner.cpp:1544
(gdb) run <personal.xml
1544	            fReaderMgr.pushReader(reader, declDTD);
(gdb) p declDTD
$1 = (xercesc_4_0::DTDEntityDecl *) 0x49ac68
(gdb) n
1547	            dtdScanner.scanExtSubsetDecl(false, true);
(gdb) n
1548	        }
(gdb) s
...
(gdb) s                     # The Janitor is about to delete the above declDTD.
90	        delete fData;
(gdb) p fData
$1 = (xercesc_4_0::DTDEntityDecl *) 0x49ac68
(gdb) b ReaderMgr.cpp:1024
(gdb) n
...
(gdb) n                     # Now we about to dereference the deleted declDTD.
1024	    if (curEntity && !curEntity->isExternal())
(gdb) p curEntity
$2 = (const xercesc_4_0::XMLEntityDecl *) 0x49ac68

Origin: apache/xerces-c@e002426
Bug: apache/xerces-c#47
Bug: apache/xerces-c#54
Bug: https://issues.apache.org/jira/browse/XERCESC-2188
Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2018-1311
Bug-Debian: https://bugs.debian.org/947431

Gbp-Pq: Name CVE-2018-1311.patch
raspbian-autopush pushed a commit to raspbian-packages/xerces-c that referenced this pull request May 25, 2024
These are the instructions for observing the bug (before this commit):

$ git clone https://github.com/apache/xerces-c.git
$ cd xerces-c
$ mkdir build
$ cd build
$ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug ..
$ make -j8
$ cp ../samples/data/personal.xml .

$ cat <<EOF >personal.dtd
<?xml encoding="ISO-8859-1"?>
<!ENTITY % nonExistentEntity SYSTEM "non-existent.ent">
%nonExistentEntity;
EOF

$ gdb samples/StdInParse
(gdb) b IGXMLScanner.cpp:1544
(gdb) run <personal.xml
1544	            fReaderMgr.pushReader(reader, declDTD);
(gdb) p declDTD
$1 = (xercesc_4_0::DTDEntityDecl *) 0x49ac68
(gdb) n
1547	            dtdScanner.scanExtSubsetDecl(false, true);
(gdb) n
1548	        }
(gdb) s
...
(gdb) s                     # The Janitor is about to delete the above declDTD.
90	        delete fData;
(gdb) p fData
$1 = (xercesc_4_0::DTDEntityDecl *) 0x49ac68
(gdb) b ReaderMgr.cpp:1024
(gdb) n
...
(gdb) n                     # Now we about to dereference the deleted declDTD.
1024	    if (curEntity && !curEntity->isExternal())
(gdb) p curEntity
$2 = (const xercesc_4_0::XMLEntityDecl *) 0x49ac68

Origin: apache/xerces-c@e002426
Bug: apache/xerces-c#47
Bug: apache/xerces-c#54
Bug: https://issues.apache.org/jira/browse/XERCESC-2188
Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2018-1311
Bug-Debian: https://bugs.debian.org/947431

Gbp-Pq: Name CVE-2018-1311.patch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants