From 86c9094e4f16d9df1f12e38a192e437d5f8476c3 Mon Sep 17 00:00:00 2001 From: waheeda bette Date: Wed, 14 Oct 2026 12:14:18 +0530 Subject: [PATCH] fix use-after-free in OpenSSL Hash copy constructor Signed-off-by: waheeda bette --- src/Library/Hash.cpp | 19 ++++++++++++++- src/Tests/Makefile.am | 1 + src/Tests/Unit/test_Hash.cpp | 47 ++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 src/Tests/Unit/test_Hash.cpp diff --git a/src/Library/Hash.cpp b/src/Library/Hash.cpp index 37f54564..0769e3d5 100644 --- a/src/Library/Hash.cpp +++ b/src/Library/Hash.cpp @@ -70,7 +70,24 @@ namespace usbguard _state = rhs._state; #endif #if defined(USBGUARD_USE_OPENSSL) - _state = rhs._state; + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + + if ((_state = EVP_MD_CTX_new()) == nullptr) { + throw std::runtime_error("Dynamic memory allocation of message digest context failed."); + } + + #else + + if ((_state = EVP_MD_CTX_create()) == nullptr) { + throw std::runtime_error("Dynamic memory allocation of message digest context failed."); + } + + #endif + + if (!EVP_MD_CTX_copy_ex(_state, rhs._state)) { + throw std::runtime_error("Copying of message digest context failed."); + } + #endif #if defined(USBGUARD_USE_LIBGCRYPT) gcry_md_copy(&_state, rhs._state); diff --git a/src/Tests/Makefile.am b/src/Tests/Makefile.am index 435a4264..c73efc5c 100644 --- a/src/Tests/Makefile.am +++ b/src/Tests/Makefile.am @@ -119,6 +119,7 @@ test_unit_SOURCES=\ Unit/test_Rule.cpp \ Unit/test_RuleParser.cpp \ Unit/test_Base64.cpp \ + Unit/test_Hash.cpp \ Unit/test_UEvent.cpp \ Unit/test_UEventParser.cpp \ Unit/test_Utility.cpp \ diff --git a/src/Tests/Unit/test_Hash.cpp b/src/Tests/Unit/test_Hash.cpp new file mode 100644 index 00000000..594f3b48 --- /dev/null +++ b/src/Tests/Unit/test_Hash.cpp @@ -0,0 +1,47 @@ +// +// Copyright (C) 2024 Red Hat, Inc. +// +// 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 +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_CATCH2_V3 + #include +#else + #include +#endif +#include + +using namespace usbguard; + +TEST_CASE("Hash", "[Hash]") +{ + SECTION("copy does not share state with the original") { + std::string expected; + { + Hash reference; + reference.update(std::string("foo")); + expected = reference.getBase64(); + } + Hash original; + original.update(std::string("foo")); + { + Hash copy(original); + copy.update(std::string("bar")); + } + REQUIRE(original.getBase64() == expected); + } +} + +/* vim: set ts=2 sw=2 et */