c++ - boost::asio::const_buffer 的安全释放

标签 c++ security boost pci-dss

出于 PA:DSS 的目的,我需要确保 boost::asio::const_buffer(例如在 boost::asio::async_write 中)在超出范围时将被清零。

使用 STL 容器,我可以像这样替换分配器/释放器:

    void deallocate(volatile pointer p, size_type n) {
        std::memset(p, 0, n * sizeof(T));
        ::operator delete(p);
    }

但是我不知道如何用 boost::asio::const_buffer 实现同样的效果,至少不是以一种仍然让 boost::asio::async_write 来使用它的方式。我也不想重新发明轮子(如果有的话)。

最佳答案

简短回答:Asio 缓冲区不拥有它们的内存,因此它们也不应负责处理它

首先,你不应该使用

std::memset(p, 0, n * sizeof(T));

使用类似 SecureZeroMemory 的函数相反:How-to ensure that compiler optimizations don't introduce a security risk?

我知道你有 volatile 因为这个原因,但它可能并不总是像你期望的那样受到尊重:

Your secure_memset function might not be sufficient. According to http://open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf there are optimizing compilers that will only zero the first byte – Daniel Trebbien Nov 9 '12 at 12:50

背景阅读:


关于 ASIO

确保您完全意识到 Boost Asio 缓冲区没有所有权语义。它们只会引用另一个对象拥有的数据。

More importantly than the question posed, you might want to check that you keep around the buffer data long enough. A common pitfall is to pass a local as a buffer:

std::string response = "OK\r\n\r\n";
asio::async_write(sock_, asio::buffer(response), ...); // OOOPS!!!

This leads to Undefined Behaviour immediately.

IOW const_buffer 是一个概念。有无数种方法可以在(您自己的)对象之上构建它:

documentation

A buffer object represents a contiguous region of memory as a 2-tuple consisting of a pointer and size in bytes. A tuple of the form {void*, size_t} specifies a mutable (modifiable) region of memory. Similarly, a tuple of the form {const void*, size_t} specifies a const (non-modifiable) region of memory. These two forms correspond to the classes mutable_buffer and const_buffer, respectively

那么,假设您有缓冲区类型

struct SecureBuffer
{
     ~SecureBuffer() { shred(); }
     size_t      size() const { return length_; }
     char const* data() const { return data_; }

     // ...
   private:
     void shred(); // uses SecureZeroMemory etc.

     std::array<char, 1024> data_ = {0};
     size_t length_ = 0u;
};

然后你可以简单地将它传递到你想使用它的地方:

SecureBuffer secret; // member variable (lifetime exceeds async operation)
// ... set data
boost::asio::async_write(sock_,
     boost::asio::buffer(secret.data(), secret.size()),
     /*...*/
    );

关于c++ - boost::asio::const_buffer 的安全释放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32558253/

相关文章:

java - Java 中的证书路径发现

python - 用于保护明文密码和 sqlite 数据库的 webapp 文件夹结构

c++ - 如何为共享内存映射选择固定地址

c++ - boost::signals2 仍然向引用死亡的对象发出信号

c++ - boost::combine() 是否与方法的输出一起使用?

c++ - Eclipse CDT+Cygwin如何处理?

C++ 构造函数

c++ - 终止在不同 QThread 中运行的 QProcess

c++ - 在C++中,如何使用在另一个文件中定义的常量变量?

windows - 开始-> 运行对话框 - "Run as Administrator"复选框?