From: Date: June 3 2008 12:00pm Subject: bzr commit into mysql-5.1-telco-6.2 tree (frazer:2613) Bug#31284 List-Archive: http://lists.mysql.com/commits/47344 X-Bug: 31284 Message-Id: <200806031000.m53A0mbC023731@forth.ndb.mysql.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1015204661==" --===============1015204661== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/frazer/bzr/mysql-5.1-telco-6.2-bugs/ ------------------------------------------------------------ revno: 2613 revision-id: frazer@stripped parent: monty@stripped committer: Frazer Clement branch nick: mysql-5.1-telco-6.2-bugs timestamp: Tue 2008-06-03 11:00:31 +0100 message: Bug# 31284 rpl_ndb_blob fails on powermacg5 Long Blob v2 code exercised buffer overrun in old Api setValue() call. Only detected on PowerMac G5 with Apple compiler. setValue() buffer overrun fixed. Various NDBAPI magic numbers de-mystified back to computed constant values modified: mysql-test/suite/ndb/r/ndb_blob.result sp1f-ndb_blob.result-20040719115359-7z65is6skg5xv6upoa7nturemb7h646j mysql-test/suite/ndb/t/ndb_blob.test sp1f-ndb_blob.test-20040718155656-sxauok4gndxbsg7tjxwjluyoq3adaqjf storage/ndb/include/kernel/signaldata/KeyInfo.hpp sp1f-keyinfo.hpp-20040414082354-corqbssvvfchibr7542ecatjtikb5wmn storage/ndb/src/ndbapi/Ndb.cpp sp1f-ndb.cpp-20040414082424-w4iietigjbat2axvr45magbzk4yg6et3 storage/ndb/src/ndbapi/NdbBlob.cpp sp1f-ndbblob.cpp-20040610100200-3kcthg74ev6adshhf5bq6plnsfcotlzh storage/ndb/src/ndbapi/NdbIndexStat.cpp sp1f-ndbindexstat.cpp-20050915003017-u46kcfhakcw4p5njv633sihzarv7xl4m storage/ndb/src/ndbapi/NdbOperationDefine.cpp sp1f-ndboperationdefine.c-20040414082425-wyjqzl6mqrnd5ckhjcskztcombchzofq storage/ndb/src/ndbapi/NdbOperationExec.cpp sp1f-ndboperationexec.cpp-20040414082425-spfhlvqpx5hh2u7nyud2l5ordg7u43eb storage/ndb/src/ndbapi/NdbOperationInt.cpp sp1f-ndboperationint.cpp-20040414082425-xa76p6frl4mmojhkkqzfmdrvg5dwy5kn storage/ndb/src/ndbapi/NdbOperationSearch.cpp sp1f-ndboperationsearch.c-20040414082425-2oopaz7wpkfxs4qbozjlx22w7hjvksyz storage/ndb/src/ndbapi/NdbRecord.hpp sp1f-ndbrecord.hpp-20070514135805-ljqy3uqwmkrmvghkhpco6yw4iniuf7qm storage/ndb/src/ndbapi/NdbScanOperation.cpp sp1f-ndbscanoperation.cpp-20040414082425-yr5memqa2kvjbeg5kez5mhmsjkkzcxmz per-file comments: mysql-test/suite/ndb/r/ndb_blob.result LongBlob setValue specific test mysql-test/suite/ndb/t/ndb_blob.test LongBlob setValue specific test storage/ndb/include/kernel/signaldata/KeyInfo.hpp IndexBound size constants storage/ndb/src/ndbapi/Ndb.cpp Hash calculation buffer reduced to size storage/ndb/src/ndbapi/NdbBlob.cpp Use of constant storage/ndb/src/ndbapi/NdbIndexStat.cpp Use of constant storage/ndb/src/ndbapi/NdbOperationDefine.cpp Buffer sizes corrected storage/ndb/src/ndbapi/NdbOperationExec.cpp Use of constant storage/ndb/src/ndbapi/NdbOperationInt.cpp Fix to buffer size storage/ndb/src/ndbapi/NdbOperationSearch.cpp Use of constants storage/ndb/src/ndbapi/NdbRecord.hpp Creation and use of constant storage/ndb/src/ndbapi/NdbScanOperation.cpp Use of constants --===============1015204661== MIME-Version: 1.0 Content-Type: text/text/x-diff; charset="us-ascii"; name="patch-2613.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline === modified file 'mysql-test/suite/ndb/r/ndb_blob.result' --- a/mysql-test/suite/ndb/r/ndb_blob.result 2008-05-21 16:39:51 +0000 +++ b/mysql-test/suite/ndb/r/ndb_blob.result 2008-06-03 10:00:31 +0000 @@ -620,3 +620,19 @@ Level Code Message drop table t1; drop table t2; +create table t1 ( +a int primary key, +giga longblob) +engine=ndb; +set @stuff = '1234567890'; +insert into t1 values (0, repeat(@stuff, 2000)); +select sha1(repeat(@stuff, 2000)); +sha1(repeat(@stuff, 2000)) +c8d94eb4127361ac22cf1c8a8f1178a37fb25e41 +select sha1(giga) from t1; +sha1(giga) +c8d94eb4127361ac22cf1c8a8f1178a37fb25e41 +select (giga = repeat(@stuff, 2000)) from t1 where a=0; +(giga = repeat(@stuff, 2000)) +1 +drop table t1; === modified file 'mysql-test/suite/ndb/t/ndb_blob.test' --- a/mysql-test/suite/ndb/t/ndb_blob.test 2008-05-21 16:39:51 +0000 +++ b/mysql-test/suite/ndb/t/ndb_blob.test 2008-06-03 10:00:31 +0000 @@ -565,3 +565,27 @@ drop table t1; drop table t2; + +# bug # 31284 +# Long Blob (8000 byte parts) with Blob v2 (+2 bytes length) +# exposed buffer overrun for old Api setValue() call used for +# writing parts. +# Check that data written into long Blob can be retrieved +# correctly +create table t1 ( + a int primary key, + giga longblob) +engine=ndb; + +# length 10 +set @stuff = '1234567890'; + +# 20,000 bytes = 3 parts +insert into t1 values (0, repeat(@stuff, 2000)); + +# Check that we get the same data back that we put in +select sha1(repeat(@stuff, 2000)); +select sha1(giga) from t1; +select (giga = repeat(@stuff, 2000)) from t1 where a=0; + +drop table t1; === modified file 'storage/ndb/include/kernel/signaldata/KeyInfo.hpp' --- a/storage/ndb/include/kernel/signaldata/KeyInfo.hpp 2008-02-19 15:00:29 +0000 +++ b/storage/ndb/include/kernel/signaldata/KeyInfo.hpp 2008-06-03 10:00:31 +0000 @@ -37,6 +37,16 @@ STATIC_CONST( HeaderLength = 3 ); STATIC_CONST( DataLength = 20 ); STATIC_CONST( MaxSignalLength = HeaderLength + DataLength ); + + /* IndexBound constants */ + STATIC_CONST( PerBoundColumnOverhead = 2 ); + /* Max number of key columns with max total key size */ + STATIC_CONST( MaxWordsPerBoundRow = \ + (PerBoundColumnOverhead * MAX_ATTRIBUTES_IN_INDEX) \ + + MAX_KEY_SIZE_IN_WORDS ); + /* Single key column with max total key size */ + STATIC_CONST( MaxWordsPerBoundColumn = \ + PerBoundColumnOverhead + MAX_KEY_SIZE_IN_WORDS ); private: Uint32 connectPtr; === modified file 'storage/ndb/src/ndbapi/Ndb.cpp' --- a/storage/ndb/src/ndbapi/Ndb.cpp 2008-02-20 09:04:29 +0000 +++ b/storage/ndb/src/ndbapi/Ndb.cpp 2008-06-03 10:00:31 +0000 @@ -550,7 +550,8 @@ Uint32 hashValue; { Uint32 buf[4]; - Uint64 tmp[1000]; + const Uint32 MaxKeySizeInLongWords= (NDB_MAX_KEY_SIZE + 7) / 8; + Uint64 tmp[ MaxKeySizeInLongWords ]; if (keyLen >= sizeof(tmp)) { === modified file 'storage/ndb/src/ndbapi/NdbBlob.cpp' --- a/storage/ndb/src/ndbapi/NdbBlob.cpp 2008-05-23 10:20:10 +0000 +++ b/storage/ndb/src/ndbapi/NdbBlob.cpp 2008-06-03 10:00:31 +0000 @@ -621,7 +621,7 @@ NdbBlob::copyKeyFromRow(const NdbRecord *record, const char *row, Buf& packedBuf, Buf& unpackedBuf) { - char buf[256]; + char buf[NdbRecord::Attr::SHRINK_VARCHAR_BUFFSIZE]; DBUG_ENTER("NdbBlob::copyKeyFromRow"); assert(record->flags & NdbRecord::RecHasAllKeys); === modified file 'storage/ndb/src/ndbapi/NdbIndexStat.cpp' --- a/storage/ndb/src/ndbapi/NdbIndexStat.cpp 2008-02-19 15:00:29 +0000 +++ b/storage/ndb/src/ndbapi/NdbIndexStat.cpp 2008-06-03 10:00:31 +0000 @@ -398,7 +398,7 @@ Uint32* keyStatData, Uint32& keyLength) { - char buf[256]; // For shrinking MySQLD varchars + char buf[NdbRecord::Attr::SHRINK_VARCHAR_BUFFSIZE]; Uint32 key_index= record->key_indexes[ keyPartNum ]; const NdbRecord::Attr *column= &record->columns[ key_index ]; === modified file 'storage/ndb/src/ndbapi/NdbOperationDefine.cpp' --- a/storage/ndb/src/ndbapi/NdbOperationDefine.cpp 2008-04-08 08:31:46 +0000 +++ b/storage/ndb/src/ndbapi/NdbOperationDefine.cpp 2008-06-03 10:00:31 +0000 @@ -481,7 +481,7 @@ int tReturnCode; Uint32 tAttrId; Uint32 tData; - Uint32 tempData[2000]; + Uint32 tempData[ NDB_MAX_TUPLE_SIZE_IN_WORDS ]; OperationType tOpType = theOperationType; OperationStatus tStatus = theStatus; @@ -884,7 +884,9 @@ DBUG_PRINT("info", ("aLen=%u", (Uint32)aLen)); // wl3717_todo not optimal.. - Uint64 buf[2048]; + const Uint32 MaxTupleSizeInLongWords= (NDB_MAX_TUPLE_SIZE + 7)/ 8; + Uint64 buf[ MaxTupleSizeInLongWords ]; + assert( aLen < (NDB_MAX_TUPLE_SIZE - 2) ); unsigned char* p = (unsigned char*)buf; p[0] = (aLen & 0xff); p[1] = (aLen >> 8); === modified file 'storage/ndb/src/ndbapi/NdbOperationExec.cpp' --- a/storage/ndb/src/ndbapi/NdbOperationExec.cpp 2008-04-01 15:37:28 +0000 +++ b/storage/ndb/src/ndbapi/NdbOperationExec.cpp 2008-06-03 10:00:31 +0000 @@ -606,7 +606,7 @@ NdbOperation::buildSignalsNdbRecord(Uint32 aTC_ConnectPtr, Uint64 aTransId) { - char buf[256]; + char buf[NdbRecord::Attr::SHRINK_VARCHAR_BUFFSIZE]; Uint32 *keyInfoPtr, *attrInfoPtr; Uint32 remain; int res; === modified file 'storage/ndb/src/ndbapi/NdbOperationInt.cpp' --- a/storage/ndb/src/ndbapi/NdbOperationInt.cpp 2008-05-27 19:12:32 +0000 +++ b/storage/ndb/src/ndbapi/NdbOperationInt.cpp 2008-06-03 10:00:31 +0000 @@ -1115,7 +1115,7 @@ m_no_disk_flag &= (col->m_storageType == NDB_STORAGETYPE_DISK ? 0:1); - Uint32 tempData[2000]; + Uint32 tempData[ NDB_MAX_TUPLE_SIZE_IN_WORDS ]; if (((UintPtr)val & 3) != 0) { memcpy(tempData, val, len); val = tempData; === modified file 'storage/ndb/src/ndbapi/NdbOperationSearch.cpp' --- a/storage/ndb/src/ndbapi/NdbOperationSearch.cpp 2008-04-08 08:31:46 +0000 +++ b/storage/ndb/src/ndbapi/NdbOperationSearch.cpp 2008-06-03 10:00:31 +0000 @@ -62,7 +62,8 @@ (long) aValuePassed)); const char* aValue = aValuePassed; - Uint64 tempData[512]; + const Uint32 MaxKeyLenInLongWords= (NDB_MAX_KEY_SIZE + 7)/8; + Uint64 tempData[ MaxKeyLenInLongWords ]; if ((theStatus == OperationDefined) && (aValue != NULL) && @@ -465,8 +466,8 @@ void NdbOperation::reorderKEYINFO() { - Uint32 data[4000]; - Uint32 size = 4000; + Uint32 data[ NDB_MAX_KEYSIZE_IN_WORDS ]; + Uint32 size = NDB_MAX_KEYSIZE_IN_WORDS; getKeyFromTCREQ(data, size); Uint32 pos = 1; Uint32 k; @@ -480,7 +481,8 @@ if (theTupleKeyDefined[j][0] == i) { Uint32 off = theTupleKeyDefined[j][1] - 1; Uint32 len = theTupleKeyDefined[j][2]; - assert(off < 4000 && off + len <= 4000); + assert(off < NDB_MAX_KEYSIZE_IN_WORDS && + off + len <= NDB_MAX_KEYSIZE_IN_WORDS); int ret = insertKEYINFO((char*)&data[off], pos, len); assert(ret == 0); pos += len; @@ -508,11 +510,12 @@ NdbApiSignal* tSignal = theTCREQ->next(); unsigned n = 0; while (pos < size) { - if (n == 20) { + if (n == KeyInfo::DataLength) { tSignal = tSignal->next(); n = 0; } - data[pos++] = tSignal->getDataPtrSend()[3 + n++]; + data[pos++] = + tSignal->getDataPtrSend()[KeyInfo::HeaderLength + n++]; } return 0; } @@ -538,7 +541,8 @@ ptrs[0].len = len; ptrs[1].ptr = 0; - Uint64 tmp[1000]; + const Uint32 MaxKeyLenInLongWords= (NDB_MAX_KEY_SIZE + 7)/ 8; + Uint64 tmp[ MaxKeyLenInLongWords ]; Uint32 hashValue; int ret = Ndb::computeHash(&hashValue, m_currentTable, === modified file 'storage/ndb/src/ndbapi/NdbRecord.hpp' --- a/storage/ndb/src/ndbapi/NdbRecord.hpp 2008-04-01 15:37:28 +0000 +++ b/storage/ndb/src/ndbapi/NdbRecord.hpp 2008-06-03 10:00:31 +0000 @@ -133,6 +133,9 @@ return (flags & IsNullable) && (row[nullbit_byte_offset] & (1 << nullbit_bit_in_byte)); } + + /* 255 bytes of data and 1 byte of length */ + STATIC_CONST( SHRINK_VARCHAR_BUFFSIZE= 256 ); /* Mysqld uses a slightly different format for storing varchar in index keys; the length is always two bytes little endian, even @@ -143,7 +146,7 @@ { const char *p= row + offset; Uint32 len= uint2korr(p); - if (len >= 256 || len >= maxSize) + if (len >= SHRINK_VARCHAR_BUFFSIZE || len >= maxSize) return false; buf[0]= (unsigned char)len; memcpy(buf+1, p+2, len); === modified file 'storage/ndb/src/ndbapi/NdbScanOperation.cpp' --- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2008-05-27 11:48:47 +0000 +++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2008-06-03 10:00:31 +0000 @@ -515,7 +515,8 @@ const char *row, Uint32 distkeyMax) { - Uint64 tmp[1000]; + const Uint32 MaxKeySizeInLongWords= (NDB_MAX_KEY_SIZE + 7) / 8; + Uint64 tmp[ MaxKeySizeInLongWords ]; char* tmpshrink = (char*)tmp; size_t tmplen = sizeof(tmp); @@ -2854,7 +2855,7 @@ const char *row, Uint32 bound_type) { - char buf[256]; + char buf[NdbRecord::Attr::SHRINK_VARCHAR_BUFFSIZE]; Uint32 currLen= theTotalNrOfKeyWordInSignal; Uint32 remaining= KeyInfo::DataLength - currLen; const NdbRecord::Attr *column= &key_record->columns[column_index]; @@ -2904,7 +2905,10 @@ theTotalNrOfKeyWordInSignal= currLen + totalLen; } else { if(!aligned || !nobytes){ - Uint32 tempData[2000]; + /* Space for Bound type, Attr header and (possibly max-sized) + * key column + */ + Uint32 tempData[ KeyInfo::MaxWordsPerBoundColumn ]; if (len > sizeof(tempData)) len= sizeof(tempData); tempData[0] = bound_type; --===============1015204661==--