MOPS-2010-058: PHP php_mysqlnd_read_error_from_line() Buffer Overflow Vulnerability

May 31st, 2010

PHP’s php_mysqlnd_read_error_from_line() trusts network data which can result in a heap based buffer overflow.

Affected versions

Affected is PHP 5.3 <= 5.3.2

Credits

The vulnerability was discovered by Stefan Esser while auditing the new Mysqlnd PHP extension.

Detailed information

The new Mysqlnd extension handles communication with mysql servers and implements the mysql protocol in the file mysqlnd_wireprotocol.c. While auditing this file several vulnerabilities were discovered. One of them is inside the php_mysqlnd_read_error_from_line() function.

if (buf_len > 2) {
    *error_no = uint2korr(p);
    p+= 2;
    /* sqlstate is following */
    if (*p == '#') {
        memcpy(sqlstate, ++p, MYSQLND_SQLSTATE_LENGTH);
        p+= MYSQLND_SQLSTATE_LENGTH;
    }
    error_msg_len = buf_len - (p - buf);
    error_msg_len = MIN(error_msg_len, error_buf_len - 1);
    memcpy(error, p, error_msg_len);
} else {
    *error_no = CR_UNKNOWN_ERROR;
    memcpy(sqlstate, unknown_sqlstate, MYSQLND_SQLSTATE_LENGTH);
}

The code above ensures that the buf_len is greater than two, but fails to take the SQLSTATE into account. Therefore a buffer overflow can happen for buf_len > 2 and buf_len < 2 + MYSQLND_SQLSTATE_LENGTH + 1. In this case error_msg_len will become negative which results in a memcpy() of 4 GB of data.

Proof of concept, exploit or instructions to reproduce

Month of PHP Security does not provide a POC for this vulnerability.

Notes

This vulnerability can be fixed by correctly checking the network supplied data.




blog comments powered by Disqus