diff options
-rw-r--r-- | myisam/mi_check.c | 22 | ||||
-rw-r--r-- | myisam/mi_key.c | 2 | ||||
-rw-r--r-- | mysql-test/r/insert_select.result | 5 | ||||
-rw-r--r-- | mysql-test/t/insert_select.test | 10 | ||||
-rw-r--r-- | mysys/safemalloc.c | 6 | ||||
-rw-r--r-- | mysys/thr_lock.c | 21 | ||||
-rw-r--r-- | sql/sql_acl.cc | 6 |
7 files changed, 56 insertions, 16 deletions
diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 92641cce13a..6caacd95386 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -896,7 +896,8 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) if (_mi_rec_unpack(info,record,info->rec_buff,block_info.rec_len) == MY_FILE_ERROR) { - mi_check_print_error(param,"Found wrong record at %s", llstr(start_recpos,llbuff)); + mi_check_print_error(param,"Found wrong record at %s", + llstr(start_recpos,llbuff)); got_error=1; } else @@ -3611,6 +3612,7 @@ err: void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, my_bool repair_only) { + byte *record; if (!info->s->base.auto_key || !(((ulonglong) 1 << (info->s->base.auto_key-1) & info->s->state.key_map))) @@ -3624,13 +3626,24 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, if (!(param->testflag & T_SILENT) && !(param->testflag & T_REP)) printf("Updating MyISAM file: %s\n", param->isam_file_name); - /* We have to use keyread here as a normal read uses info->rec_buff */ + /* + We have to use an allocated buffer instead of info->rec_buff as + _mi_put_key_in_record() may use info->rec_buff + */ + if (!(record= (byte*) my_malloc((uint) info->s->base.pack_reclength, + MYF(0)))) + { + mi_check_print_error(param,"Not enough memory for extra record"); + return; + } + mi_extra(info,HA_EXTRA_KEYREAD,0); - if (mi_rlast(info,info->rec_buff, info->s->base.auto_key-1)) + if (mi_rlast(info, record, info->s->base.auto_key-1)) { if (my_errno != HA_ERR_END_OF_FILE) { mi_extra(info,HA_EXTRA_NO_KEYREAD,0); + my_free((char*) record, MYF(0)); mi_check_print_error(param,"%d when reading last record",my_errno); return; } @@ -3642,10 +3655,11 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, ulonglong auto_increment= (repair_only ? info->s->state.auto_increment : param->auto_increment_value); info->s->state.auto_increment=0; - update_auto_increment(info,info->rec_buff); + update_auto_increment(info, record); set_if_bigger(info->s->state.auto_increment,auto_increment); } mi_extra(info,HA_EXTRA_NO_KEYREAD,0); + my_free((char*) record, MYF(0)); update_state_info(param, info, UPDATE_AUTO_INC); return; } diff --git a/myisam/mi_key.c b/myisam/mi_key.c index 5b167cc9ab0..89f6bc490fa 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -264,7 +264,7 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr, byte *blob_ptr; DBUG_ENTER("_mi_put_key_in_record"); - if (info->blobs && info->s->keyinfo[keynr].flag & HA_VAR_LENGTH_KEY) + if (info->s->base.blobs && info->s->keyinfo[keynr].flag & HA_VAR_LENGTH_KEY) { if (!(blob_ptr= mi_alloc_rec_buff(info, info->s->keyinfo[keynr].keylength, diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index c007191b562..0142ef68993 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -587,3 +587,8 @@ a b 3 t2:3 2 t2:2 drop table t1,t2; +CREATE TABLE t1 ( USID INTEGER UNSIGNED, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User CHAR(32) NOT NULL DEFAULT '<UNKNOWN>', NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL); +CREATE TABLE t2 ( USID INTEGER UNSIGNED AUTO_INCREMENT, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User TEXT NOT NULL, NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL, INDEX(USID,ServerID,NASAddr,SessionID), INDEX(AssignedAddr)); +INSERT INTO t1 VALUES (39,42,'Access-Granted','46','491721000045',2130706433,17690,NULL,NULL,'Localnet','491721000045','49172200000',754974766,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2003-07-18 00:11:21',NULL,NULL,20030718001121); +INSERT INTO t2 SELECT USID, ServerID, State, SessionID, User, NASAddr, NASPort, NASPortType, ConnectSpeed, CarrierType, CallingStationID, CalledStationID, AssignedAddr, SessionTime, PacketsIn, OctetsIn, PacketsOut, OctetsOut, TerminateCause, UnauthTime, AccessRequestTime, AcctStartTime, AcctLastTime, LastModification from t1 LIMIT 1; +drop table t1,t2; diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index d115e9c1af6..5c63f3b3bb7 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -122,3 +122,13 @@ select * from t1; replace into t1 select * from t2; select * from t1; drop table t1,t2; + +# +# Test that caused uninitialized memory access in auto_increment_key update +# + +CREATE TABLE t1 ( USID INTEGER UNSIGNED, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User CHAR(32) NOT NULL DEFAULT '<UNKNOWN>', NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL); +CREATE TABLE t2 ( USID INTEGER UNSIGNED AUTO_INCREMENT, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User TEXT NOT NULL, NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL, INDEX(USID,ServerID,NASAddr,SessionID), INDEX(AssignedAddr)); +INSERT INTO t1 VALUES (39,42,'Access-Granted','46','491721000045',2130706433,17690,NULL,NULL,'Localnet','491721000045','49172200000',754974766,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2003-07-18 00:11:21',NULL,NULL,20030718001121); +INSERT INTO t2 SELECT USID, ServerID, State, SessionID, User, NASAddr, NASPort, NASPortType, ConnectSpeed, CarrierType, CallingStationID, CalledStationID, AssignedAddr, SessionTime, PacketsIn, OctetsIn, PacketsOut, OctetsOut, TerminateCause, UnauthTime, AccessRequestTime, AcctStartTime, AcctLastTime, LastModification from t1 LIMIT 1; +drop table t1,t2; diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index bd77b4821ff..07c40fd91b6 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -374,11 +374,11 @@ void TERMINATE(FILE *file) { if (file) { - fprintf(file, "Warning: Not freed memory segments: %d\n", + fprintf(file, "Warning: Not freed memory segments: %u\n", sf_malloc_count); (void) fflush(file); } - DBUG_PRINT("safe",("sf_malloc_count: %d", sf_malloc_count)); + DBUG_PRINT("safe",("sf_malloc_count: %u", sf_malloc_count)); } /* @@ -482,7 +482,7 @@ int _sanity(const char *filename, uint lineno) pthread_mutex_lock(&THR_LOCK_malloc); #ifndef PEDANTIC_SAFEMALLOC - if (sf_malloc_tampered && sf_malloc_count < 0) + if (sf_malloc_tampered && (int) sf_malloc_count < 0) sf_malloc_count=0; #endif count=sf_malloc_count; diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 61616a4cf2b..d5236cb1ef9 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -172,10 +172,13 @@ static int check_lock(struct st_lock_list *list, const char* lock_type, return 0; } + static void check_locks(THR_LOCK *lock, const char *where, my_bool allow_no_locks) { uint old_found_errors=found_errors; + DBUG_ENTER("check_locks"); + if (found_errors < MAX_FOUND_ERRORS) { if (check_lock(&lock->write,"write",where,1,1) | @@ -252,18 +255,21 @@ static void check_locks(THR_LOCK *lock, const char *where, } if (lock->read.data) { - if ((!pthread_equal(lock->write.data->thread, - lock->read.data->thread) && - lock->write.data->type > TL_WRITE_DELAYED && - lock->write.data->type != TL_WRITE_ONLY) || - ((lock->write.data->type == TL_WRITE_CONCURRENT_INSERT || - lock->write.data->type == TL_WRITE_ALLOW_WRITE) && - lock->read_no_write_count)) + if (!pthread_equal(lock->write.data->thread, + lock->read.data->thread) && + ((lock->write.data->type > TL_WRITE_DELAYED && + lock->write.data->type != TL_WRITE_ONLY) || + ((lock->write.data->type == TL_WRITE_CONCURRENT_INSERT || + lock->write.data->type == TL_WRITE_ALLOW_WRITE) && + lock->read_no_write_count))) { found_errors++; fprintf(stderr, "Warning at '%s': Found lock of type %d that is write and read locked\n", where, lock->write.data->type); + DBUG_PRINT("warning",("At '%s': Found lock of type %d that is write and read locked\n", + where, lock->write.data->type)); + } } if (lock->read_wait.data) @@ -286,6 +292,7 @@ static void check_locks(THR_LOCK *lock, const char *where, DBUG_PRINT("error",("Found wrong lock")); } } + DBUG_VOID_RETURN; } #else /* EXTRA_DEBUG */ diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 697b5d8ffd6..d773aa5bc71 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1136,7 +1136,11 @@ find_acl_user(const char *host, const char *user) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); DBUG_PRINT("info",("strcmp('%s','%s'), compare_hostname('%s','%s'),", - user,acl_user->user,(host),(acl_user->host))); + user, + acl_user->user ? acl_user->user : "", + host, + acl_user->host.hostname ? acl_user->host.hostname : + "")); if (!acl_user->user && !user[0] || acl_user->user && !strcmp(user,acl_user->user)) { |