@@ -2291,6 +2291,8 @@ static bool mariadb_dr_connect(
2291
2291
2292
2292
imp_dbh -> async_query_in_flight = NULL ;
2293
2293
2294
+ mariadb_list_add (imp_drh -> active_imp_dbhs , imp_dbh -> list_entry , imp_dbh );
2295
+
2294
2296
return TRUE;
2295
2297
}
2296
2298
@@ -2370,10 +2372,16 @@ static bool mariadb_db_my_login(pTHX_ SV* dbh, imp_dbh_t *imp_dbh)
2370
2372
}
2371
2373
if (!found_taken_pmysql )
2372
2374
{
2375
+ /* This imp_dbh data belongs to different connection, so destructor should not touch it */
2376
+ imp_dbh -> list_entry = NULL ;
2373
2377
imp_dbh -> pmysql = NULL ;
2374
2378
mariadb_dr_do_error (dbh , CR_CONNECTION_ERROR , "Connection error: dbi_imp_data is not valid" , "HY000" );
2375
2379
return FALSE;
2376
2380
}
2381
+
2382
+ /* Add imp_dbh entry into active_imp_dbhs list */
2383
+ mariadb_list_add (imp_drh -> active_imp_dbhs , imp_dbh -> list_entry , imp_dbh );
2384
+
2377
2385
return TRUE;
2378
2386
}
2379
2387
if (DBIc_TRACE_LEVEL (imp_xxh ) >= 2 )
@@ -2452,6 +2460,9 @@ SV *mariadb_db_take_imp_data(SV *dbh, imp_xxh_t *imp_xxh, void *foo)
2452
2460
imp_drh -> taken_pmysqls = newAV ();
2453
2461
av_push (imp_drh -> taken_pmysqls , newSViv (PTR2IV (imp_dbh -> pmysql )));
2454
2462
2463
+ /* MYSQL* was taken from imp_dbh so remove it also from active_imp_dbhs list */
2464
+ mariadb_list_remove (imp_drh -> active_imp_dbhs , imp_dbh -> list_entry );
2465
+
2455
2466
return & PL_sv_no ;
2456
2467
}
2457
2468
@@ -2979,39 +2990,23 @@ static void mariadb_dr_close_mysql(pTHX_ imp_drh_t *imp_drh, MYSQL *pmysql)
2979
2990
}
2980
2991
}
2981
2992
2982
- /*
2983
- ***************************************************************************
2984
- *
2985
- * Name: mariadb_db_disconnect
2986
- *
2987
- * Purpose: Disconnect a database handle from its database
2988
- *
2989
- * Input: dbh - database handle being disconnected
2990
- * imp_dbh - drivers private database handle data
2991
- *
2992
- * Returns: 1 for success (always)
2993
- *
2994
- **************************************************************************/
2995
-
2996
- int mariadb_db_disconnect (SV * dbh , imp_dbh_t * imp_dbh )
2993
+ static void mariadb_db_close_mysql (pTHX_ imp_drh_t * imp_drh , imp_dbh_t * imp_dbh )
2997
2994
{
2998
- dTHX ;
2999
2995
AV * av ;
3000
2996
I32 i ;
3001
2997
MAGIC * mg ;
3002
2998
SV * * svp ;
3003
2999
SV * sv ;
3004
3000
SV * sth ;
3005
3001
imp_sth_t * imp_sth ;
3006
- D_imp_xxh (dbh );
3007
- D_imp_drh_from_dbh ;
3008
3002
3009
- /* We assume that disconnect will always work */
3010
- /* since most errors imply already disconnected. */
3003
+ if (DBIc_TRACE_LEVEL (imp_dbh ) >= 2 )
3004
+ PerlIO_printf (DBIc_LOGPIO (imp_dbh ), "\tmariadb_db_close_mysql: imp_dbh=%p pmysql=%p\n" , imp_dbh , imp_dbh -> pmysql );
3005
+
3011
3006
DBIc_ACTIVE_off (imp_dbh );
3012
- if ( DBIc_TRACE_LEVEL ( imp_xxh ) >= 2 )
3013
- PerlIO_printf ( DBIc_LOGPIO ( imp_xxh ), " imp_dbh->pmysql: %p\n" ,
3014
- imp_dbh -> pmysql );
3007
+
3008
+ if ( imp_dbh -> list_entry )
3009
+ mariadb_list_remove ( imp_drh -> active_imp_dbhs , imp_dbh -> list_entry );
3015
3010
3016
3011
if (imp_dbh -> pmysql )
3017
3012
{
@@ -3045,14 +3040,39 @@ int mariadb_db_disconnect(SV* dbh, imp_dbh_t* imp_dbh)
3045
3040
* CVE 2017-3302 do not do it. So do it manually to prevent crash. */
3046
3041
if (imp_sth -> stmt && imp_sth -> stmt -> mysql )
3047
3042
{
3048
- if (DBIc_TRACE_LEVEL (imp_xxh ) >= 2 )
3049
- PerlIO_printf (DBIc_LOGPIO (imp_xxh ), "Applying CVE 2017-3302 workaround for sth=0x %p\n" , imp_sth );
3043
+ if (DBIc_TRACE_LEVEL (imp_dbh ) >= 2 )
3044
+ PerlIO_printf (DBIc_LOGPIO (imp_dbh ), "Applying CVE 2017-3302 workaround for sth=%p\n" , imp_sth );
3050
3045
imp_sth -> stmt -> mysql = NULL ;
3051
3046
}
3052
3047
}
3053
3048
}
3054
3049
}
3055
3050
}
3051
+ }
3052
+
3053
+ /*
3054
+ ***************************************************************************
3055
+ *
3056
+ * Name: mariadb_db_disconnect
3057
+ *
3058
+ * Purpose: Disconnect a database handle from its database
3059
+ *
3060
+ * Input: dbh - database handle being disconnected
3061
+ * imp_dbh - drivers private database handle data
3062
+ *
3063
+ * Returns: 1 for success (always)
3064
+ *
3065
+ **************************************************************************/
3066
+
3067
+ int mariadb_db_disconnect (SV * dbh , imp_dbh_t * imp_dbh )
3068
+ {
3069
+ dTHX ;
3070
+ D_imp_drh_from_dbh ;
3071
+ PERL_UNUSED_ARG (dbh );
3072
+
3073
+ /* We assume that disconnect will always work */
3074
+ /* since most errors imply already disconnected. */
3075
+ mariadb_db_close_mysql (aTHX_ imp_drh , imp_dbh );
3056
3076
3057
3077
/* We don't free imp_dbh since a reference still exists */
3058
3078
/* The DESTROY method is the only one to 'free' memory. */
@@ -3075,10 +3095,8 @@ int mariadb_db_disconnect(SV* dbh, imp_dbh_t* imp_dbh)
3075
3095
3076
3096
int mariadb_dr_discon_all (SV * drh , imp_drh_t * imp_drh ) {
3077
3097
dTHX ;
3078
- dSP ;
3079
3098
int ret ;
3080
3099
SV * * svp ;
3081
- AV * av ;
3082
3100
I32 i ;
3083
3101
PERL_UNUSED_ARG (drh );
3084
3102
@@ -3098,34 +3116,8 @@ int mariadb_dr_discon_all (SV *drh, imp_drh_t *imp_drh) {
3098
3116
imp_drh -> taken_pmysqls = NULL ;
3099
3117
}
3100
3118
3101
- svp = hv_fetchs ((HV * )DBIc_MY_H (imp_drh ), "ChildHandles" , FALSE);
3102
- if (svp && * svp )
3103
- {
3104
- SvGETMAGIC (* svp );
3105
- if (SvROK (* svp ) && SvTYPE (SvRV (* svp )) == SVt_PVAV )
3106
- {
3107
- av = (AV * )SvRV (* svp );
3108
- for (i = AvFILL (av ); i >= 0 ; -- i )
3109
- {
3110
- svp = av_fetch (av , i , FALSE);
3111
- if (!svp || !* svp || !sv_isobject (* svp ))
3112
- continue ;
3113
-
3114
- ENTER ;
3115
- SAVETMPS ;
3116
-
3117
- PUSHMARK (SP );
3118
- EXTEND (SP , 1 );
3119
- PUSHs (sv_2mortal (newSVsv (* svp )));
3120
- PUTBACK ;
3121
-
3122
- call_method ("disconnect" , G_VOID |G_DISCARD |G_EVAL |G_KEEPERR );
3123
-
3124
- FREETMPS ;
3125
- LEAVE ;
3126
- }
3127
- }
3128
- }
3119
+ while (imp_drh -> active_imp_dbhs )
3120
+ mariadb_db_close_mysql (aTHX_ imp_drh , (imp_dbh_t * )imp_drh -> active_imp_dbhs -> data );
3129
3121
3130
3122
ret = 1 ;
3131
3123
0 commit comments