From: Date: April 27 2006 12:54pm Subject: bk commit into 4.1 tree (kroki:1.2462) BUG#16372 List-Archive: http://lists.mysql.com/commits/5629 X-Bug: 16372 Message-Id: <200604271054.k3RAsgWG011252@moonlight.intranet> Below is the list of changes that have just been committed into a local 4.1 repository of tomash. When tomash does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.2462 06/04/27 14:54:36 kroki@stripped +1 -0 Bug#16372: Server crashes when test 'conc_sys' is running Concurrent read and update of privilege structures (like simultaneous run of SHOW GRANTS and ADD USER) could result in server crash. Ensure that proper locking of ACL structures is done. sql/sql_acl.cc 1.175 06/04/27 14:54:31 kroki@stripped +31 -6 Ensure that access to ACL data is protected by acl_cache->lock mutex. Use system_charset_info for host names consistently. # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: kroki # Host: moonlight.intranet # Root: /home/tomash/src/mysql_ab/mysql-4.1-bug16372 --- 1.174/sql/sql_acl.cc 2006-03-06 13:02:54 +03:00 +++ 1.175/sql/sql_acl.cc 2006-04-27 14:54:31 +04:00 @@ -894,6 +894,8 @@ USER_RESOURCES *mqh, ulong privileges) { + safe_mutex_assert_owner(&acl_cache->lock); + for (uint i=0 ; i < acl_users.elements ; i++) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); @@ -942,6 +944,9 @@ ulong privileges) { ACL_USER acl_user; + + safe_mutex_assert_owner(&acl_cache->lock); + acl_user.user=*user ? strdup_root(&mem,user) : 0; update_hostname(&acl_user.host, *host ? strdup_root(&mem, host): 0); acl_user.access=privileges; @@ -973,6 +978,8 @@ static void acl_update_db(const char *user, const char *host, const char *db, ulong privileges) { + safe_mutex_assert_owner(&acl_cache->lock); + for (uint i=0 ; i < acl_dbs.elements ; i++) { ACL_DB *acl_db=dynamic_element(&acl_dbs,i,ACL_DB*); @@ -1358,6 +1365,9 @@ { DBUG_ENTER("find_acl_user"); DBUG_PRINT("enter",("host: '%s' user: '%s'",host,user)); + + safe_mutex_assert_owner(&acl_cache->lock); + for (uint i=0 ; i < acl_users.elements ; i++) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); @@ -1370,7 +1380,7 @@ if (!acl_user->user && !user[0] || acl_user->user && !strcmp(user,acl_user->user)) { - if (exact ? !my_strcasecmp(&my_charset_latin1, host, + if (exact ? !my_strcasecmp(system_charset_info, host, acl_user->host.hostname ? acl_user->host.hostname : "") : compare_hostname(&acl_user->host,host,host)) @@ -2445,6 +2455,7 @@ create_new_users= test_if_create_new_users(thd); int result=0; rw_wrlock(&LOCK_grant); + pthread_mutex_lock(&acl_cache->lock); MEM_ROOT *old_root= thd->mem_root; thd->mem_root= &memex; @@ -2460,10 +2471,8 @@ continue; } /* Create user if needed */ - pthread_mutex_lock(&acl_cache->lock); error=replace_user_table(thd, tables[0].table, *Str, 0, revoke_grant, create_new_users); - pthread_mutex_unlock(&acl_cache->lock); if (error) { result= -1; // Remember error @@ -2552,6 +2561,7 @@ } grant_option=TRUE; thd->mem_root= old_root; + pthread_mutex_unlock(&acl_cache->lock); rw_unlock(&LOCK_grant); if (!result) send_ok(thd); @@ -3203,6 +3213,9 @@ DBUG_RETURN(-1); } + rw_rdlock(&LOCK_grant); + VOID(pthread_mutex_lock(&acl_cache->lock)); + for (counter=0 ; counter < acl_users.elements ; counter++) { const char *user,*host; @@ -3217,6 +3230,9 @@ } if (counter == acl_users.elements) { + VOID(pthread_mutex_unlock(&acl_cache->lock)); + rw_unlock(&LOCK_grant); + my_error(ER_NONEXISTING_GRANT, MYF(0), lex_user->user.str, lex_user->host.str); DBUG_RETURN(-1); @@ -3230,10 +3246,12 @@ lex_user->host.str,NullS); field_list.push_back(field); if (protocol->send_fields(&field_list,1)) - DBUG_RETURN(-1); + { + VOID(pthread_mutex_unlock(&acl_cache->lock)); + rw_unlock(&LOCK_grant); - rw_wrlock(&LOCK_grant); - VOID(pthread_mutex_lock(&acl_cache->lock)); + DBUG_RETURN(-1); + } /* Add first global access grants */ { @@ -3540,10 +3558,15 @@ void get_mqh(const char *user, const char *host, USER_CONN *uc) { ACL_USER *acl_user; + + pthread_mutex_lock(&acl_cache->lock); + if (initialized && (acl_user= find_acl_user(host,user, FALSE))) uc->user_resources= acl_user->user_resource; else bzero((char*) &uc->user_resources, sizeof(uc->user_resources)); + + pthread_mutex_unlock(&acl_cache->lock); } int open_grant_tables(THD *thd, TABLE_LIST *tables) @@ -3601,6 +3624,8 @@ { ACL_USER *acl_user= 0; uint counter; + + safe_mutex_assert_owner(&acl_cache->lock); for (counter= 0 ; counter < acl_users.elements ; counter++) {