Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 623632 (CVE-2017-10788) - <dev-perl/DBD-mysql-4.44.0: Denial of Service
Summary: <dev-perl/DBD-mysql-4.44.0: Denial of Service
Status: RESOLVED FIXED
Alias: CVE-2017-10788
Product: Gentoo Security
Classification: Unclassified
Component: Vulnerabilities (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Gentoo Security
URL: http://www.openwall.com/lists/oss-sec...
Whiteboard: B3 [noglsa cve]
Keywords:
Depends on: CVE-2017-10789
Blocks:
  Show dependency tree
 
Reported: 2017-07-03 11:45 UTC by Kristian Fiskerstrand (RETIRED)
Modified: 2018-05-19 22:04 UTC (History)
2 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kristian Fiskerstrand (RETIRED) gentoo-dev 2017-07-03 11:45:55 UTC
CVE:

The DBD::mysql module through 4.043 for Perl allows remote attackers to cause a denial of service (use-after-free and application crash) or possibly have unspecified other impact by triggering (1) certain error responses from a MySQL server or (2) a loss of a network connection to a MySQL server. The use-after-free defect was introduced by relying on incorrect Oracle mysql_stmt_close documentation and code examples. 

From $URL:
Hello!

MySQL applications written according to Oracle's MySQL documentation & 
examples for mysql_stmt_close() function call are vulnerable to use-
after-free defect.

In mysql_stmt_close() documentation [1] for return value is written:
"Zero for success. Nonzero if an error occurred." And there are defined 
two errors: CR_SERVER_GONE_ERROR CR_UNKNOWN_ERROR. From other parts of 
documentation can be understood that error messages for statements could 
be obtained by mysql_stmt_error() function [2].

Whole example of usage is written in mysql_stmt_execute() function [3]. 
The relevant part for mysql_stmt_close() is at the end of example:

/* Close the statement */
if (mysql_stmt_close(stmt))
{
  fprintf(stderr, " failed while closing the statement\n");
  fprintf(stderr, " %s\n", mysql_stmt_error(stmt));
  exit(0);
}

And here is a problem, use-after-free defect. Current implementation of 
mysql_stmt_close() function unconditionally free passed statement 
structure and therefore following mysql_stmt_error() call is defective 
to use-after-free.

Relevant part of implementation of mysql_stmt_close() function is:

my_bool mysql_stmt_close(MYSQL_STMT *stmt)
{
  int rc=0;
...
  if ((rc= stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt)))
    set_stmt_errmsg(stmt, &mysql->net);
...
  my_free(stmt);
  return rc;
}

As you can see it stores real error message into stmt structure, but at 
the end it is freed. Which means error message is no longer available 
and caller is not able to read it (even via mysql_stmt_error() call).

As such defective code is in example of the usage, probably couple of 
MySQL applications written according to that defective documentations 
are affected to this issue.

There is reported real bug for MySQL DBI driver that is affected by this 
issue [4]. Reporter probably compiled MySQL library or driver itself 
with some compiler options which could detect buffer overflows and 
uncovered this issue.


In April 17 I reported this issue to oCERT team and it was forwarded to 
MySQL, MariaDB and Percona security teams.

MariaDB team answered that this is problem in Oracle & MySQL and their 
documentation as MariaDB do not have such vulnerable example in their 
documentation.

Oracle team was unwilling to tell anything, provide any information how 
to handle such issue or what to do, therefore with suggestion from oCERT 
I decided to make this report public and open public discussion for 
other people on oss-security list how to handle this problem.


As Oracle fully ignored this problem and have not stated if problem is 
in documentation, implementation or both, I see probably 3 different 
solutions:

1) Documentation with examples is correct and this is how it should be 
used. What is wrong is implementation.

It would mean that function mysql_stmt_error() and mysql_stmt_errno() 
needs to specially handle statement pointers which were already freed by 
mysql_stmt_close(). This can be done e.g. by storing hash table of 
pointers and assigning for them last received error.

Or clarifying that mysql_stmt_close() does not always free passed 
memory. Because from current description in documentation it is not 
fully unambiguous what happen if function fails.

In this case implementation of mysql_stmt_close(), mysql_stmt_error() 
and mysql_stmt_errno() are vulnerable to use-after-free defect and needs 
to be fixed. And it should be assigned CVE for MySQL for this problem.

2) Implementation is correct, documentation is wrong.

Documentation needs to be fixed to properly describe how are those 
functions implemented. Important note must be that if function 
mysql_stmt_close() fails it is not possible to take error code via 
mysql_stmt_error() or mysql_stmt_errno(). Also examples needs to be 
fixed.

And then all MySQL applications which were written according to wrong 
documentation needs to be fixed and for each one needs to be assigned 
CVE. Number of those applications is unknown, to get it first every 
application which uses libmysqlclient.so needs to be checked and 
verified. What we know now is that MySQL Perl DBI is affected.

3) Documentation is wrong, but implementation of mysql_stmt_close() is 
not-so-correct.

Which would mean that return value of mysql_stmt_close() is fully 
meaningless as there is no way to recover from bad state. Currently 
mysql_stmt_close() unconditionally free memory for statement, so no 
recover is possible.

There are two options what can be done:

* Always return value zero which means no error occurred. This basically 
mitigate use-after-free vulnerability in Oracle's documentation and also 
all applications which were written according to documentation.

* When error occurred, do not free memory of passed structure. This 
would mean that following mysql_stmt_error() call would not be affected 
by use-after-free anymore.


As Oracle ignored this security related problem (***) I would like to 
ask, how to handle this problem? And to which software needs to be 
requested for CVE? To MySQL itself (as described in option 1)? Or to 
every one software which uses MySQL (as described in option 2)?

I think you understand me, that MySQL DBD driver needs to be fixed, 
ideally ASAP. Bug report on github is from April 13 [4]. And as Oracle 
is not willing to do anything, I hope that people on public oss-security 
list give some advice how to handle this situation.

I'm CCing all relevant security teams, when replaying please do not 
forget to include them + me. Thanks!

--

[1] - https://dev.mysql.com/doc/refman/5.7/en/mysql-stmt-close.html
[2] - https://dev.mysql.com/doc/refman/5.7/en/mysql-stmt-error.html
[3] - https://dev.mysql.com/doc/refman/5.7/en/mysql-stmt-execute.html
[4] - https://github.com/perl5-dbi/DBD-mysql/issues/120

(***) - This is not a first time! Previous two security issues reported 
by me were ignored too. Oracle is the worst company in handling security 
issues. It is useless to report them anything. They just start threaten 
if you make information about issue public. And they are not competent 
to start working on it or fix it in less then 6 months! Really I suggest 
to not report any security bug to Oracle, it is just wasting of time.
Comment 1 Kent Fredric (IRC: kent\n) (RETIRED) gentoo-dev 2018-01-24 04:18:03 UTC
Upstream seem to have no intent on fixing this in DBD-mysql: https://github.com/perl5-dbi/DBD-mysql/issues/120#issuecomment-359835586
Comment 2 Kent Fredric (IRC: kent\n) (RETIRED) gentoo-dev 2018-01-24 04:24:17 UTC
I guess "seem" is the operative word, the referenced commit also was landed in master for 4.044. Yay.

https://github.com/perl5-dbi/DBD-mysql/commit/79718cd69ec73203877bf7d13f0b8273e931f20f
Comment 3 Larry the Git Cow gentoo-dev 2018-01-24 04:41:12 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=0d845674dece9cded838f4184eeeaf33fea0a0ae

commit 0d845674dece9cded838f4184eeeaf33fea0a0ae
Author:     Kent Fredric <kentnl@gentoo.org>
AuthorDate: 2018-01-24 04:33:33 +0000
Commit:     Kent Fredric <kentnl@gentoo.org>
CommitDate: 2018-01-24 04:40:44 +0000

    dev-perl/DBD-mysql: Bump to version 4.44.0
    
    - Remove embedded support
      - https://bugs.gentoo.org/644174
      - https://bugs.gentoo.org/598048
      - removal from older versions may happen later
    
    Upstream:
    - Fix for CVE-2017-10788 ( https://bugs.gentoo.org/623632 )
    - Fix for CVE-2017-10789 ( https://bugs.gentoo.org/623942 )
    - Enforce SSL settings for BACKRONYM and Riddle
    - Fix parsing of mysql_config --libs output  in Configure
    - Return INTs with ZEROFILL as strings
    - Some fixes for 5.26-dot-in-inc
    
    Bug: https://bugs.gentoo.org/598048
    Bug: https://bugs.gentoo.org/623632
    Bug: https://bugs.gentoo.org/623942
    Bug: https://bugs.gentoo.org/644174
    Package-Manager: Portage-2.3.18, Repoman-2.3.6

 dev-perl/DBD-mysql/DBD-mysql-4.44.0.ebuild         |  64 +++++++++
 dev-perl/DBD-mysql/Manifest                        |   1 +
 .../DBD-mysql-4.044-amvis-type-conversions.patch   |  56 ++++++++
 .../files/DBD-mysql-4.044-no-dot-inc.patch         | 151 +++++++++++++++++++++
 4 files changed, 272 insertions(+)}
Comment 4 Aaron Bauman (RETIRED) gentoo-dev 2018-05-19 22:04:24 UTC
GLSA Vote: No

Cleanup will occur in bug #623942