File perl-DBD-mysql-CVE-2016-1249.patch of Package perl-DBD-mysql.7188
From 793b72b1a0baa5070adacaac0e12fd995a6fbabe Mon Sep 17 00:00:00 2001
From: root <patg@patg.net>
Date: Wed, 16 Nov 2016 03:40:40 +0000
Subject: [PATCH] Added Pali's fix for CVE-2016-1249
---
dbdimp.c | 18 +------
lib/Bundle/DBD/mysql.pm | 2 +-
lib/DBD/mysql.pm | 2 +-
mysql.xs | 128 +++------------------------------------------
t/40server_prepare_crash.t | 8 ++-
6 files changed, 22 insertions(+), 139 deletions(-)
Index: DBD-mysql-4.021/dbdimp.c
===================================================================
--- DBD-mysql-4.021.orig/dbdimp.c
+++ DBD-mysql-4.021/dbdimp.c
@@ -2608,7 +2608,7 @@ dbd_st_prepare(
dTHX;
#if MYSQL_VERSION_ID >= SERVER_PREPARE_VERSION
char *str_ptr;
- int col_type, prepare_retval, limit_flag=0;
+ int prepare_retval, limit_flag=0;
MYSQL_BIND *bind, *bind_end;
imp_sth_phb_t *fbind;
#endif
@@ -2797,7 +2797,6 @@ dbd_st_prepare(
if (DBIc_NUM_PARAMS(imp_sth) > 0)
{
- int has_statement_fields= imp_sth->stmt->fields != 0;
/* Allocate memory for bind variables */
imp_sth->bind= alloc_bind(DBIc_NUM_PARAMS(imp_sth));
imp_sth->fbind= alloc_fbind(DBIc_NUM_PARAMS(imp_sth));
@@ -2811,20 +2810,7 @@ dbd_st_prepare(
bind < bind_end ;
bind++, fbind++, i++ )
{
- /*
- if this statement has a result set, field types will be
- correctly identified. If there is no result set, such as
- with an INSERT, fields will not be defined, and all buffer_type
- will default to MYSQL_TYPE_VAR_STRING
- */
- col_type= (has_statement_fields ?
- imp_sth->stmt->fields[i].type : MYSQL_TYPE_STRING);
-
- bind->buffer_type= mysql_to_perl_type(col_type);
-
- if (DBIc_TRACE_LEVEL(imp_xxh) >= 2)
- PerlIO_printf(DBIc_LOGPIO(imp_xxh), "\t\tmysql_to_perl_type returned %d\n", col_type);
-
+ bind->buffer_type= MYSQL_TYPE_STRING;
bind->buffer= NULL;
bind->length= &(fbind->length);
bind->is_null= (char*) &(fbind->is_null);
Index: DBD-mysql-4.021/mysql.xs
===================================================================
--- DBD-mysql-4.021.orig/mysql.xs
+++ DBD-mysql-4.021/mysql.xs
@@ -259,15 +259,11 @@ do(dbh, statement, attr=Nullsv, ...)
STRLEN slen;
char *str_ptr, *statement_ptr, *buffer;
int has_binded;
- int col_type= MYSQL_TYPE_STRING;
- int buffer_is_null= 0;
int buffer_length= slen;
int buffer_type= 0;
- int param_type= SQL_VARCHAR;
int use_server_side_prepare= 0;
MYSQL_STMT *stmt= NULL;
MYSQL_BIND *bind= NULL;
- imp_sth_phb_t *fbind= NULL;
#endif
ASYNC_CHECK_XS(dbh);
#if MYSQL_VERSION_ID >= MULTIPLE_RESULT_SET_VERSION
@@ -360,137 +356,36 @@ do(dbh, statement, attr=Nullsv, ...)
*/
int i;
num_params= items - 3;
- /*num_params = mysql_stmt_param_count(stmt);*/
- Newz(0, params, sizeof(*params)*num_params, struct imp_sth_ph_st);
Newz(0, bind, (unsigned int) num_params, MYSQL_BIND);
- Newz(0, fbind, (unsigned int) num_params, imp_sth_phb_t);
for (i = 0; i < num_params; i++)
{
int defined= 0;
- params[i].value= ST(i+3);
+ SV *param= ST(i+3);
- if (params[i].value)
+ if (param)
{
- if (SvMAGICAL(params[i].value))
- mg_get(params[i].value);
- if (SvOK(params[i].value))
+ if (SvMAGICAL(param))
+ mg_get(param);
+ if (SvOK(param))
defined= 1;
}
if (defined)
{
- buffer= SvPV(params[i].value, slen);
- buffer_is_null= 0;
+ buffer= SvPV(param, slen);
buffer_length= slen;
+ buffer_type= MYSQL_TYPE_STRING;
}
else
{
buffer= NULL;
- buffer_is_null= 1;
buffer_length= 0;
- }
-
- /*
- if this statement has a result set, field types will be
- correctly identified. If there is no result set, such as
- with an INSERT, fields will not be defined, and all
- buffer_type will default to MYSQL_TYPE_VAR_STRING
- */
- col_type= (stmt->fields) ? stmt->fields[i].type : MYSQL_TYPE_STRING;
-
- switch (col_type) {
-#if MYSQL_VERSION_ID > 50003
- case MYSQL_TYPE_NEWDECIMAL:
-#endif
- case MYSQL_TYPE_DECIMAL:
- param_type= SQL_DECIMAL;
- buffer_type= MYSQL_TYPE_DOUBLE;
- break;
-
- case MYSQL_TYPE_DOUBLE:
- param_type= SQL_DOUBLE;
- buffer_type= MYSQL_TYPE_DOUBLE;
- break;
-
- case MYSQL_TYPE_FLOAT:
- buffer_type= MYSQL_TYPE_DOUBLE;
- param_type= SQL_FLOAT;
- break;
-
- case MYSQL_TYPE_SHORT:
- buffer_type= MYSQL_TYPE_DOUBLE;
- param_type= SQL_FLOAT;
- break;
-
- case MYSQL_TYPE_TINY:
- buffer_type= MYSQL_TYPE_DOUBLE;
- param_type= SQL_FLOAT;
- break;
-
- case MYSQL_TYPE_LONG:
- buffer_type= MYSQL_TYPE_LONG;
- param_type= SQL_BIGINT;
- break;
-
- case MYSQL_TYPE_INT24:
- case MYSQL_TYPE_YEAR:
- buffer_type= MYSQL_TYPE_LONG;
- param_type= SQL_INTEGER;
- break;
-
- case MYSQL_TYPE_LONGLONG:
- /* perl handles long long as double
- * so we'll set this to string */
- buffer_type= MYSQL_TYPE_STRING;
- param_type= SQL_VARCHAR;
- break;
-
- case MYSQL_TYPE_NEWDATE:
- case MYSQL_TYPE_DATE:
- buffer_type= MYSQL_TYPE_STRING;
- param_type= SQL_DATE;
- break;
-
- case MYSQL_TYPE_TIME:
- buffer_type= MYSQL_TYPE_STRING;
- param_type= SQL_TIME;
- break;
-
- case MYSQL_TYPE_TIMESTAMP:
- buffer_type= MYSQL_TYPE_STRING;
- param_type= SQL_TIMESTAMP;
- break;
-
- case MYSQL_TYPE_VAR_STRING:
- case MYSQL_TYPE_STRING:
- case MYSQL_TYPE_DATETIME:
- buffer_type= MYSQL_TYPE_STRING;
- param_type= SQL_VARCHAR;
- break;
-
- case MYSQL_TYPE_BLOB:
- buffer_type= MYSQL_TYPE_BLOB;
- param_type= SQL_BINARY;
- break;
-
- case MYSQL_TYPE_GEOMETRY:
- buffer_type= MYSQL_TYPE_BLOB;
- param_type= SQL_BINARY;
- break;
-
-
- default:
- buffer_type= MYSQL_TYPE_STRING;
- param_type= SQL_VARCHAR;
- break;
+ buffer_type= MYSQL_TYPE_NULL;
}
bind[i].buffer_type = buffer_type;
bind[i].buffer_length= buffer_length;
bind[i].buffer= buffer;
- fbind[i].length= buffer_length;
- fbind[i].is_null= buffer_is_null;
- params[i].type= param_type;
}
has_binded= 0;
}
@@ -502,8 +397,6 @@ do(dbh, statement, attr=Nullsv, ...)
&has_binded);
if (bind)
Safefree(bind);
- if (fbind)
- Safefree(fbind);
if(mysql_stmt_close(stmt))
{