Fixed memory overrun when doing REPAIR on table with multi-part auto_increment key where one part was a packed CHAR

myisam/mi_check.c:
  Fixed memory overrun in _mi_put_key_in_record
myisam/mi_key.c:
  Fixed unnecessary memory allocation
mysql-test/r/insert_select.result:
  Added test case for memory corruption
mysql-test/t/insert_select.test:
  Added test case for memory corruption
mysys/safemalloc.c:
  Removed compiler warnings
sql/sql_acl.cc:
  Fixed core dump when running with --debug
This commit is contained in:
unknown 2003-07-18 04:04:24 +03:00
commit 06517dfed3
6 changed files with 42 additions and 9 deletions

View file

@ -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;
}

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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))
{