【问题标题】:Secure deallocation of boost::asio::const_bufferboost::asio::const_buffer 的安全释放
【发布时间】:2015-12-10 01:38:18
【问题描述】:

出于 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 消耗它的方式。我也不想重新发明轮子(如果有的话)。

【问题讨论】:

    标签: c++ security boost pci-dss


    【解决方案1】:

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

    首先,你应该使用

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

    改用SecureZeroMemory 之类的函数:How-to ensure that compiler optimizations don't introduce a security risk?

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

    您的secure_memset 功能可能不够用。根据http://open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf,有优化编译器只会将第一个字节归零– Daniel Trebbien Nov 9 '12 at 12:50

    背景阅读:


    到 ASIO

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

    比提出的问题更重要的是,您可能需要检查是否将缓冲区数据保留足够长的时间。一个常见的陷阱是将本地作为缓冲区传递:

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

    这会立即导致Undefined Behaviour

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

    documentation

    缓冲区对象将内存的连续区域表示为由指针和字节大小组成的 2 元组。 {void*, size_t} 形式的元组指定内存的可变(可修改)区域。类似地,{const void*, size_t} 形式的元组指定了一个 const(不可修改)内存区域。这两种形式分别对应mutable_bufferconst_buffer这两个类

    所以,假设你有你的缓冲区类型

    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()),
         /*...*/
        );
    

    【讨论】:

      猜你喜欢
      • 2011-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-22
      • 1970-01-01
      相关资源
      最近更新 更多