Back-port upstream fix for CVE-2007-5925. diff -Naur mysql-5.0.45.orig/innobase/include/db0err.h mysql-5.0.45/innobase/include/db0err.h --- mysql-5.0.45.orig/innobase/include/db0err.h 2007-07-04 09:06:59.000000000 -0400 +++ mysql-5.0.45/innobase/include/db0err.h 2007-12-13 12:44:05.000000000 -0500 @@ -57,6 +57,18 @@ buffer pool (for big transactions, InnoDB stores the lock structs in the buffer pool) */ +#define DB_FOREIGN_DUPLICATE_KEY 46 /* foreign key constraints + activated by the operation would + lead to a duplicate key in some + table */ +#define DB_TOO_MANY_CONCURRENT_TRXS 47 /* when InnoDB runs out of the + preconfigured undo slots, this can + only happen when there are too many + concurrent transactions */ +#define DB_UNSUPPORTED 48 /* when InnoDB sees any artefact or + a feature that it can't recoginize or + work with e.g., FT indexes created by + a later version of the engine. */ /* The following are partial failure codes */ #define DB_FAIL 1000 diff -Naur mysql-5.0.45.orig/innobase/include/page0cur.h mysql-5.0.45/innobase/include/page0cur.h --- mysql-5.0.45.orig/innobase/include/page0cur.h 2007-07-04 09:06:10.000000000 -0400 +++ mysql-5.0.45/innobase/include/page0cur.h 2007-12-13 12:44:05.000000000 -0500 @@ -22,6 +22,7 @@ /* Page cursor search modes; the values must be in this order! */ +#define PAGE_CUR_UNSUPP 0 #define PAGE_CUR_G 1 #define PAGE_CUR_GE 2 #define PAGE_CUR_L 3 diff -Naur mysql-5.0.45.orig/sql/ha_innodb.cc mysql-5.0.45/sql/ha_innodb.cc --- mysql-5.0.45.orig/sql/ha_innodb.cc 2007-07-04 09:06:48.000000000 -0400 +++ mysql-5.0.45/sql/ha_innodb.cc 2007-12-13 12:44:05.000000000 -0500 @@ -526,6 +526,9 @@ } return(HA_ERR_LOCK_TABLE_FULL); + } else if (error == DB_UNSUPPORTED) { + + return(HA_ERR_UNSUPPORTED); } else { return(-1); // Unknown error } @@ -3689,11 +3692,21 @@ and comparison of non-latin1 char type fields in innobase_mysql_cmp() to get PAGE_CUR_LE_OR_EXTENDS to work correctly. */ - - default: assert(0); + case HA_READ_MBR_CONTAIN: + case HA_READ_MBR_INTERSECT: + case HA_READ_MBR_WITHIN: + case HA_READ_MBR_DISJOINT: + my_error(ER_TABLE_CANT_HANDLE_SPKEYS, MYF(0)); + return(PAGE_CUR_UNSUPP); + /* do not use "default:" in order to produce a gcc warning: + enumeration value '...' not handled in switch + (if -Wswitch or -Wall is used) + */ } - return(0); + my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "this functionality"); + + return(PAGE_CUR_UNSUPP); } /* @@ -3831,11 +3844,18 @@ last_match_mode = (uint) match_mode; - innodb_srv_conc_enter_innodb(prebuilt->trx); + if (mode != PAGE_CUR_UNSUPP) { - ret = row_search_for_mysql((byte*) buf, mode, prebuilt, match_mode, 0); + innodb_srv_conc_enter_innodb(prebuilt->trx); - innodb_srv_conc_exit_innodb(prebuilt->trx); + ret = row_search_for_mysql((byte*) buf, mode, prebuilt, + match_mode, 0); + + innodb_srv_conc_exit_innodb(prebuilt->trx); + } else { + + ret = DB_UNSUPPORTED; + } if (ret == DB_SUCCESS) { error = 0; @@ -5150,8 +5170,16 @@ mode2 = convert_search_mode_to_innobase(max_key ? max_key->flag : HA_READ_KEY_EXACT); - n_rows = btr_estimate_n_rows_in_range(index, range_start, - mode1, range_end, mode2); + if (mode1 != PAGE_CUR_UNSUPP && mode2 != PAGE_CUR_UNSUPP) { + + n_rows = btr_estimate_n_rows_in_range(index, range_start, + mode1, range_end, + mode2); + } else { + + n_rows = 0; + } + dtuple_free_for_mysql(heap1); dtuple_free_for_mysql(heap2);