zoukankan      html  css  js  c++  java
  • RSA_new()初始化和RSA_free()释放RSA结构体后依然会有内存泄漏(转)

    在使用OpenSSL的RSA加解密的时候,发现RSA_new()初始化和RSA_free()释放RSA结构体后依然会有内存泄漏。网上Baidu、Google之,发现这个相关信息很少(至少中文搜索结果是这样,不知是研究这个的人太少还是这个太基础了。。。),最后终于在某个E文论坛上找到了解决办法。在这里总结了一下,供大家参考。我的OpenSSL版本是0.9.8l。(by 月落上弦)

    具体如下:
    RSA * rsa = RSA_new();
    RSA_free( rsa );

    产生内存泄漏:

    复制代码
    Detected memory leaks!
    Dumping objects ->
    {140} normal block at 0x003B97A0, 12 bytes long.
     Data: <  ;         > B8 96 3B 00 00 00 00 00 06 00 00 00 
    {139} normal block at 0x003B9750, 16 bytes long.
     Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    {138} normal block at 0x003B9700, 20 bytes long.
     Data: <    P ;         > 00 00 00 00 50 97 3B 00 00 00 00 00 04 00 00 00 
    {137} normal block at 0x003B96B8, 12 bytes long.
     Data: <      ;     > 06 00 00 00 00 97 3B 00 00 00 00 00 
    {136} normal block at 0x003B9638, 64 bytes long.
     Data: <                > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
    {135} normal block at 0x003B9598, 96 bytes long.
     Data: <8 ;   A   A     > 38 96 3B 00 C0 FD 41 00 B0 FD 41 00 08 00 00 00 
    Object dump complete.
    复制代码

    解决方法很简单:

    调用OpenSSL的crypto库,在退出前需要调用API "CRYPTO_cleanup_all_ex_data",清除管理CRYPTO_EX_DATA的全局hash表中的数据,避免内存泄漏。如下:

    RSA * rsa = RSA_new();
    RSA_free( rsa );
    CRYPTO_cleanup_all_ex_data(); 

    这样就没有内存泄漏了。

    需要注意的是,CRYPTO_cleanup_all_ex_data()不能在potential race-conditions条件在调用(不太懂这个术语,我理解的意思是当函数外部存在RSA结构体的时候,在函数内部执行CRYPTO_cleanup_all_ex_data()将导致函数外的RSA结构体也被清理掉),因此最好在程序结束的时候才调用。

    关于CRYPTO_cleanup_all_ex_data()的注释说明和代码如下:

    复制代码
    /* Release all "ex_data" state to prevent memory leaks. This can't be made
     * thread-safe without overhauling a lot of stuff, and shouldn't really be
     * called under potential race-conditions anyway (it's for program shutdown
     * after all). */
    void CRYPTO_cleanup_all_ex_data(void)
        {
        IMPL_CHECK
        EX_IMPL(cleanup)();
        }
    复制代码

    同样,其他相应的模块也需要在使用后清理:

    CONF_modules_unload(1);        //for conf
    EVP_cleanup();                 //For EVP
    ENGINE_cleanup();              //for engine
    CRYPTO_cleanup_all_ex_data();  //generic 
    ERR_remove_state(0);           //for ERR
    ERR_free_strings();            //for ERR

      http://www.cnblogs.com/moonset7/archive/2009/12/30/1635770.html 月落上弦

  • 相关阅读:
    Pyhton入门 笔记 第二天 变量与运算符
    Pyhton入门 笔记 第一天 数据类型
    HTML 中的特殊字符
    Extjs--12种布局方式
    .NET easyUI tree树状结构
    SqlServer中嵌套事务使用--事务计数指示 BEGIN 和 COMMIT 语句的数目不匹配 --根本问题
    事务回滚 DEMO
    SQL 事物回滚
    一步一步教你玩转.NET Framework的配置文件app.config
    C# tostring() 方法
  • 原文地址:https://www.cnblogs.com/djiankuo/p/5972146.html
Copyright © 2011-2022 走看看