Bug #73123 Possible access to freed memory in IS_FREE_LOCK() and IS_USED_LOCK().
Submitted: 26 Jun 2014 13:24 Modified: 24 Sep 2014 1:36
Reporter: Dmitry Lenev Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Locking Severity:S3 (Non-critical)
Version:5.5.37-bzr, 5.6.17-bzr OS:Any
Assigned to: CPU Architecture:Any

[26 Jun 2014 13:24] Dmitry Lenev
Description:
Implementations of IS_FREE_LOCK() and IS_USED_LOCK() function contain race condition due to which they can access freed memory in scenario when user-lock being checked is concurrently freed. Accessing to freed memory might result in wrong return value from these functions and occasionally to server crashes.

How to repeat:
The simplest way is to check the code in sql/item_func.cc:

longlong Item_func_is_free_lock::val_int()
{
...  

  mysql_mutex_lock(&LOCK_user_locks);
  ull= (User_level_lock *) my_hash_search(&hash_user_locks, (uchar*) res->ptr(),
                                          (size_t) res->length());
  mysql_mutex_unlock(&LOCK_user_locks);
  if (!ull || !ull->locked)

Note that there is no guarantee that "ull" points to valid/unfreed memory after LOCK_user_locks is unlocked.
[24 Sep 2014 1:36] Paul DuBois
Noted in 5.5.41, 5.6.22, 5.7.6 changelogs.

The IS_FREE_LOCK() and IS_USED_LOCK() function implementations
contained a race condition due to which they could access freed
memory when a user lock was concurrently checked and freed. Accessing
freed memory could result in an incorect function return value or
server exit.
[3 Dec 2014 14:29] Laurynas Biveinis
$ bzr log -r 4714
------------------------------------------------------------
revno: 4714
committer: Praveenkumar Hulakund <praveenkumar.hulakund@oracle.com>
branch nick: mysql-5.5
timestamp: Tue 2014-09-16 11:28:46 +0530
message:
  Bug#19070633 - POSSIBLE ACCESS TO FREED MEMORY IN IS_FREE_LOCK()
                  AND IS_USED_LOCK().
  
  Analysis:
  -----------
  In functions Item_func_is_free_lock::val_int() and 
  Item_func_is_used_lock::val_int(), for the specified user lock
  name, pointer to its "User_level_lock" object is obtained from hash
  "hash_user_locks". Mutex "LOCK_user_locks" is acquired for this
  and released immediately. And we are accessing members of
  User_level_lock after releasing the mutex. If same user lock is
  deleted(released) from concurrent thread then accessing members
  results in invalid(freed) memory access issue.
  
  Deleting of user lock is also protected from the mutex
  "LOCK_user_locks". Since this mutex is released in "val_int" 
  functions mentioned above, delete operation proceeds while concurrent
  thread tries to access its members.
  
  With the test case, valgrind reports invalid read issues in val_int
  functions.
  
  Fix:
  -----------
  To fix this issue, in "val_int" function of classes
  "Item_func_is_free_lock" and "Item_func_is_used_lock", now releasing
  mutex "LOCK_user_locks" after accessing User_level_lock members.