c++ - glibc mysql_stmt_close 释放坏内存?

标签 c++ mysql pam xrdp

红帽 RHEL 6+; MySQL(最新)

这很奇怪。我有一个工作应用程序,它实际上是 Linux 上 PAM 系统的 .so 插件。安装插件后,我可以使用 ssh、控制台和名为 x2go 的工具登录。如果我关闭 x2go 并使用 xrdp,那么它会抛出异常

# *** glibc detected *** /usr/sbin/xrdp-sesman: free(): invalid pointer: 0x0000000002560718 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x75f4e)[0x7f25a9923f4e]
/lib64/libc.so.6(+0x78cad)[0x7f25a9926cad]
/usr/lib64/mysql/libmysqlclient.so.18(mysql_stmt_close+0x61)    [0x7f259ba6b611]
/usr/local/sbin/myPlugin      /pam_myPlugin.so(_ZN16UserTracking_Lib7MySQLDB7MySQLDB22insertIntomyPluginESt4listINS_11EventRecordESaIS3_EE+0x5dd)[0x7f25a010bedd]
/usr/local/sbin/myPlugin/pam_myPlugin.so(InsertEventRecord+0x498)[0x7f25a0107458]
/usr/local/sbin/myPlugin/pam_myPlugin.so(call_myPlugin+0x6a1)[0x7f25a0106301]
/lib64/libpam.so.0[0x39d8402cee]
/lib64/libpam.so.0(pam_open_session+0x28)[0x39d8407168]
/usr/sbin/xrdp-sesman[0x4077c7]
/usr/sbin/xrdp-sesman[0x404e23]
/usr/sbin/xrdp-sesman[0x40598a]
/usr/sbin/xrdp-sesman[0x403f41]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x7f25a98ccd5d]
/usr/sbin/xrdp-sesman[0x402d99]
...

涉及的代码段为:

MYSQL_STMT *sth;
int numBindCols = 5;
std::string dateTmp = MyAppUtilities::MyAppUtilities::UpperCase(item.getDate().c_str());

if (dateTmp.compare("NOW()") == 0) {
    snprintf(insertSQL, 1024,
            "INSERT INTO %s (blah, blah, blah, blah, blah, date) \
                                VALUES(UPPER(?), UPPER(?), UPPER(?), UPPER(?), UPPER(?), NOW())",
            MyApp_Lib::MySQLDB::DBMyAppTableName.c_str());
} else {
    snprintf(insertSQL, 1024,
            "INSERT INTO %s (blah, blah, blah, blah, blah, date) \
                                VALUES(UPPER(?), UPPER(?), UPPER(?), UPPER(?), UPPER(?), ?)",
            MyApp_Lib::MySQLDB::DBMyAppTableName.c_str());

    numBindCols = 6;
}

if ((sth = mysql_stmt_init(&mysql)) == NULL) {
    sprintf(error, "%s: MySQL could not init statement: %s",
            __func__, mysql_stmt_error(sth));
    syslog(LOG_AUTHPRIV | LOG_DEBUG, "%s", error);
    throw MyAppUtilities::MyException(error);
}

if (mysql_stmt_prepare(sth, insertSQL,
        strlen(insertSQL)) != 0) {
    sprintf(error, "%s: MySQL could not prepare query: %s",
            __func__, mysql_stmt_error(sth));
    syslog(LOG_AUTHPRIV | LOG_DEBUG, "%s", error);
    throw MyAppUtilities::MyException(error);
}

int col = 0;

MYSQL_BIND bind[6];
memset(bind, 0, sizeof (bind));

[... several bind blocks... ]

if (mysql_stmt_bind_param(sth, bind) != 0) {
    sprintf(error, "%s: MySQL could not bind values: %s",
            __func__, mysql_stmt_error(sth));
    syslog(LOG_AUTHPRIV | LOG_DEBUG, "%s", error);
    throw MyAppUtilities::MyException(error);
}

if (mysql_stmt_execute(sth) != 0) {
    sprintf(error, "%s: MySQL could not execute: %s",
            __func__, mysql_stmt_error(sth));
    syslog(LOG_AUTHPRIV | LOG_DEBUG, "%s", error);
    throw MyAppUtilities::MyException(error);
}

if (mysql_stmt_close(sth) != 0) {
    sprintf(error, "%s: MySQL could not close stmt handle: %s",
            __func__, mysql_stmt_error(sth));
    syslog(LOG_AUTHPRIV | LOG_DEBUG, "%s", error);
    throw MyAppUtilities::MyException(error);
}

sth 的创建和处理方式与示例相同:https://dev.mysql.com/doc/refman/5.0/en/mysql-stmt-execute.html 我不明白这个问题。想法?

最佳答案

看来您是 CVE-2017-3302 的受害者。您需要将您的 MySQL 客户端至少升级到版本 5.5.55 或 5.6.21 或 5.7.5。或者 MariaDB 客户端至少到 5.5.55 或 10.0.30 或 10.1.22 或 10.2.5 版本。

参见:http://www.openwall.com/lists/oss-security/2017/02/11/11

关于c++ - glibc mysql_stmt_close 释放坏内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33000414/

相关文章:

c++ - 在哪里放置模板特化

MySQL在多个语句中包含if else时触发错误1064

c++ - 带参数的 Pthread 成员函数

c++ - 使用 Google Protocol Buffer 的 CMake

Zend 的 Mysql CASE 语句用法

mysql - Django 与远程 MySQL

linux - 如何使用没有 root 权限的 PAM 验证用户名/密码

Java JAAS 与 Linux PAM 集成(包括密码时效)

linux - 如何调试 Linux PAM 模块?

c++ - C++11 中的空宏参数合法吗?