Skip to content

Commit c6152e1

Browse files
committed
Fixed memory leaks with CryptoContext
1 parent bff238d commit c6152e1

File tree

7 files changed

+75
-40
lines changed

7 files changed

+75
-40
lines changed

include/tscore/CryptoHash.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#pragma once
2424

2525
#include "tscore/BufferWriter.h"
26+
#include <openssl/evp.h>
2627
#include <string_view>
2728

2829
/// Apache Traffic Server commons.
@@ -132,6 +133,9 @@ class CryptoContextBase
132133
/// @note This is just as fast as the previous style, as a new context must be initialized
133134
/// every time this is done.
134135
bool hash_immediate(CryptoHash &hash, void const *data, int length);
136+
137+
protected:
138+
EVP_MD_CTX *_ctx = nullptr;
135139
};
136140

137141
inline bool
@@ -159,29 +163,31 @@ class CryptoContext : public CryptoContextBase
159163
UNSPECIFIED,
160164
#if TS_ENABLE_FIPS == 0
161165
MD5,
162-
MMH,
163166
#endif
164167
SHA256,
165168
}; ///< What type of hash we really are.
166169
static HashType Setting;
167170

168-
/// Size of storage for placement @c new of hashing context.
169-
static size_t const OBJ_SIZE = 256;
171+
~CryptoContext()
172+
{
173+
delete _base;
174+
_base = nullptr;
175+
}
170176

171177
protected:
172-
char _obj[OBJ_SIZE]; ///< Raw storage for instantiated context.
178+
CryptoContextBase *_base = nullptr;
173179
};
174180

175181
inline bool
176182
CryptoContext::update(void const *data, int length)
177183
{
178-
return reinterpret_cast<CryptoContextBase *>(_obj)->update(data, length);
184+
return _base->update(data, length);
179185
}
180186

181187
inline bool
182188
CryptoContext::finalize(CryptoHash &hash)
183189
{
184-
return reinterpret_cast<CryptoContextBase *>(_obj)->finalize(hash);
190+
return _base->finalize(hash);
185191
}
186192

187193
ts::BufferWriter &bwformat(ts::BufferWriter &w, ts::BWFSpec const &spec, ats::CryptoHash const &hash);

include/tscore/MD5.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@
2929

3030
class MD5Context : public ats::CryptoContextBase
3131
{
32-
protected:
33-
EVP_MD_CTX *_ctx;
34-
3532
public:
3633
MD5Context()
3734
{

include/tscore/SHA256.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,23 @@
2929

3030
class SHA256Context : public ats::CryptoContextBase
3131
{
32-
protected:
33-
EVP_MD_CTX *ctx;
34-
3532
public:
3633
SHA256Context()
3734
{
38-
ctx = EVP_MD_CTX_new();
39-
EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr);
35+
_ctx = EVP_MD_CTX_new();
36+
EVP_DigestInit_ex(_ctx, EVP_sha256(), nullptr);
4037
}
41-
~SHA256Context() { EVP_MD_CTX_free(ctx); }
38+
~SHA256Context() { EVP_MD_CTX_free(_ctx); }
4239
/// Update the hash with @a data of @a length bytes.
4340
bool
4441
update(void const *data, int length) override
4542
{
46-
return EVP_DigestUpdate(ctx, data, length);
43+
return EVP_DigestUpdate(_ctx, data, length);
4744
}
4845
/// Finalize and extract the @a hash.
4946
bool
5047
finalize(CryptoHash &hash) override
5148
{
52-
return EVP_DigestFinal_ex(ctx, hash.u8, nullptr);
49+
return EVP_DigestFinal_ex(_ctx, hash.u8, nullptr);
5350
}
5451
};

src/traffic_server/traffic_server.cc

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -768,18 +768,6 @@ CB_After_Cache_Init()
768768
start = ink_atomic_swap(&delay_listen_for_cache, -1);
769769
emit_fully_initialized_message();
770770

771-
#if TS_ENABLE_FIPS == 0
772-
// Check for cache BC after the cache is initialized and before listen, if possible.
773-
if (cacheProcessor.min_stripe_version._major < CACHE_DB_MAJOR_VERSION) {
774-
// Versions before 23 need the MMH hash.
775-
if (cacheProcessor.min_stripe_version._major < 23) {
776-
Debug("cache_bc", "Pre 4.0 stripe (cache version %d.%d) found, forcing MMH hash for cache URLs",
777-
cacheProcessor.min_stripe_version._major, cacheProcessor.min_stripe_version._minor);
778-
URLHashContext::Setting = URLHashContext::MMH;
779-
}
780-
}
781-
#endif
782-
783771
if (1 == start) {
784772
// The delay_listen_for_cache value was 1, therefore the main function
785773
// delayed the call to start_HttpProxyServer until we got here. We must

src/tscore/CryptoHash.cc

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,25 +45,16 @@ CryptoContext::CryptoContext()
4545
case UNSPECIFIED:
4646
#if TS_ENABLE_FIPS == 0
4747
case MD5:
48-
new (_obj) MD5Context;
49-
break;
50-
case MMH:
51-
new (_obj) MMHContext;
48+
_base = new MD5Context;
5249
break;
5350
#else
5451
case SHA256:
55-
new (_obj) SHA256Context;
52+
_base = new SHA256Context;
5653
break;
5754
#endif
5855
default:
5956
ink_release_assert(!"Invalid global URL hash context");
6057
};
61-
#if TS_ENABLE_FIPS == 0
62-
static_assert(CryptoContext::OBJ_SIZE >= sizeof(MD5Context), "bad OBJ_SIZE");
63-
static_assert(CryptoContext::OBJ_SIZE >= sizeof(MMHContext), "bad OBJ_SIZE");
64-
#else
65-
static_assert(CryptoContext::OBJ_SIZE >= sizeof(SHA256Context), "bad OBJ_SIZE");
66-
#endif
6758
}
6859

6960
/**

src/tscore/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ test_tscore_SOURCES = \
170170
unit_tests/test_ArgParser.cc \
171171
unit_tests/test_BufferWriter.cc \
172172
unit_tests/test_BufferWriterFormat.cc \
173+
unit_tests/test_CryptoHash.cc \
173174
unit_tests/test_Extendible.cc \
174175
unit_tests/test_History.cc \
175176
unit_tests/test_ink_inet.cc \
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
@file Test for CryptoHash
3+
4+
@section license License
5+
6+
Licensed to the Apache Software Foundation (ASF) under one
7+
or more contributor license agreements. See the NOTICE file
8+
distributed with this work for additional information
9+
regarding copyright ownership. The ASF licenses this file
10+
to you under the Apache License, Version 2.0 (the
11+
"License"); you may not use this file except in compliance
12+
with the License. You may obtain a copy of the License at
13+
14+
http://www.apache.org/licenses/LICENSE-2.0
15+
16+
Unless required by applicable law or agreed to in writing, software
17+
distributed under the License is distributed on an "AS IS" BASIS,
18+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19+
See the License for the specific language governing permissions and
20+
limitations under the License.
21+
*/
22+
23+
#include <array>
24+
#include <string_view>
25+
26+
#include "tscore/ink_assert.h"
27+
#include "tscore/ink_defs.h"
28+
#include "tscore/CryptoHash.h"
29+
#include "catch.hpp"
30+
31+
TEST_CASE("CrypoHash", "[libts][CrypoHash]")
32+
{
33+
CryptoHash hash;
34+
ats::CryptoContext ctx;
35+
std::string_view test = "asdfsfsdfljhasdfkjasdkfuy239874kasjdf";
36+
std::string_view sha256 = "2602CBA2CC0331EB7C455E9F36030B32CE9BB432A90759075F5A702772BE123B";
37+
std::string_view md5 = "480AEF8C24AA94B80DC6214ECEC8CD1A";
38+
39+
// Hash the test data
40+
ctx.update(test.data(), test.size());
41+
ctx.finalize(hash);
42+
43+
// Write the output to a string
44+
char buffer[(CRYPTO_HASH_SIZE * 2) + 1];
45+
hash.toHexStr(buffer);
46+
47+
// Compair to a known hash value
48+
if (CryptoContext::Setting == CryptoContext::SHA256) {
49+
REQUIRE(strlen(buffer) == sha256.size());
50+
REQUIRE(memcmp(sha256.data(), buffer, sha256.size()) == 0);
51+
} else {
52+
REQUIRE(strlen(buffer) == md5.size());
53+
REQUIRE(memcmp(md5.data(), buffer, md5.size()) == 0);
54+
}
55+
}

0 commit comments

Comments
 (0)