From 1320c9d61d54f16aac9b5b0617881e68c470fabe Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Sun, 30 Apr 2017 22:46:44 +0300 Subject: [PATCH] [fbreader] Feed expat with a random hash salt That's supposed to prevent DoS attacks based on predicting hash function behavior (although it's hard to imagine that someone would ever decide to attack the poor little Books app). --- .../src/xml/expat/ZLXMLReaderInternal.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/fbreader/fbreader/zlibrary/core/src/xml/expat/ZLXMLReaderInternal.cpp b/fbreader/fbreader/zlibrary/core/src/xml/expat/ZLXMLReaderInternal.cpp index 1044f18..e819551 100644 --- a/fbreader/fbreader/zlibrary/core/src/xml/expat/ZLXMLReaderInternal.cpp +++ b/fbreader/fbreader/zlibrary/core/src/xml/expat/ZLXMLReaderInternal.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2004-2010 Geometer Plus + * Copyright (C) 2015-2017 Slava Monich * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +27,11 @@ #include "ZLXMLReaderInternal.h" #include "../ZLXMLReader.h" +#include +#include +#include +#include + void ZLXMLReaderInternal::fCharacterDataHandler(void *userData, const char *text, int len) { ZLXMLReader &reader = *(ZLXMLReader*)userData; if (!reader.isInterrupted()) { @@ -107,10 +113,17 @@ static void parseDTD(XML_Parser parser, const std::string &fileName) { ZLXMLReaderInternal::ZLXMLReaderInternal(ZLXMLReader &reader, const char *encoding) : myReader(reader) { myParser = XML_ParserCreate(encoding); myInitialized = false; - // Set salt to anything non-zero. Otherwise this parser won't be able - // to use the entity cache filled by the child DTD parsers. For more + // Set salt to a random non-zero number. Otherwise this parser won't be + // able to use the entity cache filled by the child DTD parsers. For more // details see CVE-2012-0876 and http://sourceforge.net/p/expat/bugs/496/ - XML_SetHashSalt(myParser, 42); + unsigned long salt = 0; + int urandom = open("/dev/urandom", O_RDONLY); + if (urandom >= 0) { + read(urandom, &salt, sizeof(salt)); + close(urandom); + } + if (!salt) salt = 42; + XML_SetHashSalt(myParser, salt); } ZLXMLReaderInternal::~ZLXMLReaderInternal() {