Bug #59464 Race condition in row_vers_build_for_semi_consistent_read
Submitted: 13 Jan 2011 9:12 Modified: 10 Feb 2011 20:01
Reporter: Marko Mäkelä Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version:5.1+ OS:Any
Assigned to: Marko Mäkelä CPU Architecture:Any
Tags: innodb, innodb_locks_unsafe_for_binlog, semi-consistent

[13 Jan 2011 9:12] Marko Mäkelä
Description:
This came up while working on a feature.

The function row_vers_build_for_semi_consistent_read(), introduced in the fix of Bug #3300, is checking version_trx->conc_state while not holding kernel_mutex:

		mutex_enter(&kernel_mutex);
		version_trx = trx_get_on_id(version_trx_id);
		mutex_exit(&kernel_mutex);

		if (!version_trx
		    || version_trx->conc_state == TRX_NOT_STARTED
		    || version_trx->conc_state == TRX_COMMITTED_IN_MEMORY) {

The version_trx can be committed, and it could be freed before the tests are executed. Because transaction objects are typically not freed immediately after commit, it is unclear if this can have caused any real issues. On a busy system where the thread has been suspended for a longish time between the mutex_exit and the dereferencing of version_trx, it could.

How to repeat:
Read the code.

Suggested fix:
		mutex_enter(&kernel_mutex);
		version_trx = trx_get_on_id(version_trx_id);

		if (version_trx
		    && (version_trx->conc_state == TRX_NOT_STARTED
			|| version_trx->conc_state == TRX_COMMITTED_IN_MEMORY)) {
			version_trx = NULL;
		}

		mutex_exit(&kernel_mutex);

		if (version_trx != NULL) {
[13 Jan 2011 9:18] Marko Mäkelä
Sorry, I got the condition in the last line in Suggested fix the wrong way around. It should be as follows:

		mutex_enter(&kernel_mutex);
		version_trx = trx_get_on_id(version_trx_id);

		if (version_trx
		    && (version_trx->conc_state == TRX_NOT_STARTED
			|| version_trx->conc_state == TRX_COMMITTED_IN_MEMORY)) {
			version_trx = NULL;
		}

		mutex_exit(&kernel_mutex);

		if (version_trx == NULL) {
[25 Jan 2011 9:55] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/129525
[25 Jan 2011 9:55] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/129526
[30 Jan 2011 16:59] Bugs System
Pushed into mysql-5.1 5.1.56 (revid:vasil.dimov@oracle.com-20110130164158-1q99a41kb2wvkw3a) (version source revid:vasil.dimov@oracle.com-20110130164158-1q99a41kb2wvkw3a) (merge vers: 5.1.56) (pib:24)
[30 Jan 2011 17:00] Bugs System
Pushed into mysql-trunk 5.6.2 (revid:vasil.dimov@oracle.com-20110130165639-1pr3opz839b98q5j) (version source revid:vasil.dimov@oracle.com-20110130165522-m0o6al0pn5ig9kv3) (merge vers: 5.6.2) (pib:24)
[30 Jan 2011 17:00] Bugs System
Pushed into mysql-5.5 5.5.10 (revid:vasil.dimov@oracle.com-20110130165343-he9art47agq1a3gr) (version source revid:vasil.dimov@oracle.com-20110130165137-5lvzsq9j29j0hp1s) (merge vers: 5.5.10) (pib:24)