blob: 0cbb8d9308b1fc7d2c9af36804f1e097df3e1ac5 [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIBBRILLO_BRILLO_SECURE_ALLOCATOR_H_
#define LIBBRILLO_BRILLO_SECURE_ALLOCATOR_H_
#include <memory>
#include <brillo/brillo_export.h>
namespace brillo {
// SecureAllocator is a stateless derivation of std::allocator that clears
// the contents of the object on deallocation.
template <typename T>
class BRILLO_PRIVATE SecureAllocator : public std::allocator<T> {
public:
using typename std::allocator<T>::pointer;
using typename std::allocator<T>::size_type;
using typename std::allocator<T>::value_type;
// Implicit std::allocator constructors.
template <typename U> struct rebind {
typedef SecureAllocator<U> other;
};
// Allocation/deallocation: use the std::allocation functions but make sure
// that on deallocation, the contents of the element are cleared out.
pointer allocate(size_type n, pointer = {}) {
return std::allocator<T>::allocate(n);
}
virtual void deallocate(pointer p, size_type n) {
clear_contents(p, n * sizeof(value_type));
std::allocator<T>::deallocate(p, n);
}
protected:
// Force memset to not be optimized out.
// Original source commit: 31b02653c2560f8331934e879263beda44c6cc76
// Repo: https://android.googlesource.com/platform/external/minijail
#if defined(__clang__)
#define __attribute_no_opt __attribute__((optnone))
#else
#define __attribute_no_opt __attribute__((__optimize__(0)))
#endif
// Zero-out all bytes in the allocated buffer.
virtual void __attribute_no_opt clear_contents(pointer v, size_type n) {
if (!v)
return;
memset(v, 0, n);
}
#undef __attribute_no_opt
};
} // namespace brillo
#endif // LIBBRILLO_BRILLO_SECURE_ALLOCATOR_H_