fixed heap use after free vulnerability CVE-2021-21900

as reported in TALOS-2021-1351 / CVE-2021-21900,
DRW_TableEntry::parseCode had the potential to trigger an use after free exception with a malformed DXF file.
This commit is contained in:
Roman Telezhynskyi 2021-11-22 18:22:27 +02:00
parent 783a3faaeb
commit 47e0e3d0f3
3 changed files with 57 additions and 30 deletions

View File

@ -24,6 +24,7 @@
- Option to disable the automatic search for updates.
- [smart-pattern/valentina#153] To add text search bar in History window.
- Improve for a search bar.
- Backport fix vulnerability CVE-2021-21900.
# Valentina 0.7.49 July 1, 2021
- Fix crash.

View File

@ -48,26 +48,46 @@ void DRW_TableEntry::parseCode(int code, dxfReader *reader){
case 1011:
case 1012:
case 1013:
curr = new DRW_Variant();
curr->addCoord();
curr->setCoordX(reader->getDouble());
curr->code = code;
extData.push_back(curr);
// don't trust in X, Y, Z order!
if (curr != nullptr)
{
curr->setCoordX(reader->getDouble());
}
else
{
curr = new DRW_Variant( code, DRW_Coord( reader->getDouble(), 0.0, 0.0));
extData.push_back(curr);
}
break;
case 1020:
case 1021:
case 1022:
case 1023:
if (curr)
// don't trust in X, Y, Z order!
if (curr != nullptr)
{
curr->setCoordY(reader->getDouble());
}
else
{
curr = new DRW_Variant(code, DRW_Coord( 0.0, reader->getDouble(), 0.0));
extData.push_back(curr);
}
break;
case 1030:
case 1031:
case 1032:
case 1033:
if (curr)
// don't trust in X, Y, Z order!
if (curr != nullptr)
{
curr->setCoordZ(reader->getDouble());
curr=nullptr;
}
else
{
curr = new DRW_Variant(code, DRW_Coord(0.0, 0.0, reader->getDouble()));
extData.push_back(curr);
}
break;
case 1040:
case 1041:

View File

@ -54,20 +54,15 @@ namespace DRW {
*/
class DRW_TableEntry {
public:
//initializes default values
DRW_TableEntry()
: tType(DRW::UNKNOWNT),
handle(),
parentHandle(0),
name(),
flags(0),
extData(),
curr(nullptr)
{}
virtual~DRW_TableEntry() {
for (std::vector<DRW_Variant*>::iterator it=extData.begin(); it!=extData.end(); ++it)
virtual~DRW_TableEntry()
{
for (std::vector<DRW_Variant*>::iterator it = extData.begin(); it != extData.end(); ++it)
{
delete *it;
}
extData.clear();
}
@ -79,34 +74,45 @@ public:
name(e.name),
flags(e.flags),
extData(),
curr(e.curr)
curr(nullptr)
{
for (std::vector<DRW_Variant*>::const_iterator it=e.extData.begin(); it!=e.extData.end(); ++it){
extData.push_back(new DRW_Variant(*(*it)));
for (std::vector<DRW_Variant*>::const_iterator it = e.extData.begin(); it != e.extData.end(); ++it)
{
DRW_Variant *src = *it;
DRW_Variant *dst = new DRW_Variant(*src);
extData.push_back(dst);
if (src == e.curr)
{
curr = dst;
}
}
}
protected:
void parseCode(int code, dxfReader *reader);
void reset(){
void reset()
{
flags = 0;
for (std::vector<DRW_Variant*>::iterator it=extData.begin(); it!=extData.end(); ++it)
for (std::vector<DRW_Variant*>::iterator it = extData.begin(); it != extData.end(); ++it)
{
delete *it;
}
extData.clear();
curr = nullptr;
}
public:
enum DRW::TTYPE tType; /*!< enum: entity type, code 0 */
duint32 handle; /*!< entity identifier, code 5 */
int parentHandle; /*!< Soft-pointer ID/handle to owner object, code 330 */
UTF8STRING name; /*!< entry name, code 2 */
int flags; /*!< Flags relevant to entry, code 70 */
std::vector<DRW_Variant*> extData; /*!< FIFO list of extended data, codes 1000 to 1071*/
enum DRW::TTYPE tType {DRW::UNKNOWNT}; /*!< enum: entity type, code 0 */
duint32 handle {0}; /*!< entity identifier, code 5 */
int parentHandle {0}; /*!< Soft-pointer ID/handle to owner object, code 330 */
UTF8STRING name{}; /*!< entry name, code 2 */
int flags {0}; /*!< Flags relevant to entry, code 70 */
std::vector<DRW_Variant*> extData{}; /*!< FIFO list of extended data, codes 1000 to 1071*/
private:
DRW_TableEntry &operator=(const DRW_TableEntry &) Q_DECL_EQ_DELETE;
// cppcheck-suppress unsafeClassCanLeak
DRW_Variant* curr;
DRW_Variant* curr{nullptr};
};