From 92dbb4caee6426862136429982d795e8815307ee Mon Sep 17 00:00:00 2001 From: Simon Giesecke Date: Thu, 11 Jul 2019 12:59:23 +0200 Subject: [PATCH] Problem: no C++ style secure memory allocator available Solution: Added secure_allocator_t based on libsodium's memory management functions when available --- CMakeLists.txt | 1 + Makefile.am | 1 + src/curve_mechanism_base.hpp | 2 + src/secure_allocator.hpp | 103 +++++++++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 src/secure_allocator.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c6a7d930..fcde23c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -871,6 +871,7 @@ set(cxx-sources req.hpp router.hpp scatter.hpp + secure_allocator.hpp select.hpp server.hpp session_base.hpp diff --git a/Makefile.am b/Makefile.am index 2ac8999a..9aba4cf0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -179,6 +179,7 @@ src_libzmq_la_SOURCES = \ src/router.hpp \ src/scatter.cpp \ src/scatter.hpp \ + src/secure_allocator.hpp \ src/select.cpp \ src/select.hpp \ src/server.cpp \ diff --git a/src/curve_mechanism_base.hpp b/src/curve_mechanism_base.hpp index 6128df1c..72b9b969 100644 --- a/src/curve_mechanism_base.hpp +++ b/src/curve_mechanism_base.hpp @@ -48,6 +48,8 @@ #include "mechanism_base.hpp" #include "options.hpp" +#include + namespace zmq { class curve_mechanism_base_t : public virtual mechanism_base_t diff --git a/src/secure_allocator.hpp b/src/secure_allocator.hpp new file mode 100644 index 00000000..47eeafc8 --- /dev/null +++ b/src/secure_allocator.hpp @@ -0,0 +1,103 @@ +/* + Copyright (c) 2007-2019 Contributors as noted in the AUTHORS file + + This file is part of libzmq, the ZeroMQ core engine in C++. + + libzmq is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License (LGPL) as published + by the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + As a special exception, the Contributors give you permission to link + this library with independent modules to produce an executable, + regardless of the license terms of these independent modules, and to + copy and distribute the resulting executable under terms of your choice, + provided that you also meet, for each linked independent module, the + terms and conditions of the license of that module. An independent + module is a module which is not derived from or based on this library. + If you modify this library, you must extend this exception to your + version of the library. + + libzmq 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +#ifndef __ZMQ_SECURE_ALLOCATOR_HPP_INCLUDED__ +#define __ZMQ_SECURE_ALLOCATOR_HPP_INCLUDED__ + +#include "platform.hpp" +#include "macros.hpp" + +#ifdef ZMQ_HAVE_CURVE + +#if defined(ZMQ_USE_LIBSODIUM) +#include "sodium.h" +#endif + +#include + +namespace zmq +{ +#if defined(ZMQ_USE_LIBSODIUM) +template struct secure_allocator_t +{ + typedef T value_type; + + secure_allocator_t () {} + template + secure_allocator_t (const secure_allocator_t &) ZMQ_NOEXCEPT + { + } + T *allocate (std::size_t n) ZMQ_NOEXCEPT + { + T *res = static_cast (sodium_allocarray (sizeof (T), n)); + alloc_assert (res); + return res; + } + void deallocate (T *p, std::size_t) ZMQ_NOEXCEPT { sodium_free (p); } + + // the following is only required with C++98 + // TODO maybe make this conditionally compiled + typedef T *pointer; + typedef const T *const_pointer; + typedef T &reference; + typedef const T &const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + template struct rebind + { + typedef secure_allocator_t other; + }; + + void construct (pointer p, const_reference val) + { + new ((void *) p) value_type (val); + } + void destroy (pointer p) { p->~value_type (); } + size_type max_size () const { return SIZE_MAX; } +}; +template +bool operator== (const secure_allocator_t &, const secure_allocator_t &) +{ + return true; +} +template +bool operator!= (const secure_allocator_t &, const secure_allocator_t &) +{ + return false; +} +#else +template struct secure_allocator_t : std::allocator +{ +}; +#endif +} + +#endif + +#endif