@@ -101,6 +101,7 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
101101 int expired = 0 ;
102102 int i ;
103103
104+
104105 if (msr -> txcfg -> data_dir == NULL ) {
105106 msr_log (msr , 1 , "collection_retrieve_ex: Unable to retrieve collection (name \"%s\", key \"%s\"). Use "
106107 "SecDataDir to define data directory first." , log_escape (msr -> mp , col_name ),
@@ -119,10 +120,18 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
119120 key .dsize = col_key_len + 1 ;
120121
121122 if (existing_dbm == NULL ) {
123+ rc = apr_global_mutex_lock (msr -> modsecurity -> dbm_lock );
124+ if (rc != APR_SUCCESS ) {
125+ msr_log (msr , 1 , "collection_retrieve_ex: Failed to lock proc mutex: %s" ,
126+ get_apr_error (msr -> mp , rc ));
127+ goto cleanup ;
128+ }
129+
122130 rc = apr_sdbm_open (& dbm , dbm_filename , APR_READ | APR_SHARELOCK ,
123131 CREATEMODE , msr -> mp );
124132 if (rc != APR_SUCCESS ) {
125133 dbm = NULL ;
134+ apr_global_mutex_unlock (msr -> modsecurity -> dbm_lock );
126135 goto cleanup ;
127136 }
128137 }
@@ -156,6 +165,7 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
156165 /* Close after "value" used from fetch or memory may be overwritten. */
157166 if (existing_dbm == NULL ) {
158167 apr_sdbm_close (dbm );
168+ apr_global_mutex_unlock (msr -> modsecurity -> dbm_lock );
159169 dbm = NULL ;
160170 }
161171
@@ -202,12 +212,19 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
202212 */
203213 if (apr_table_get (col , "KEY" ) == NULL ) {
204214 if (existing_dbm == NULL ) {
215+ rc = apr_global_mutex_lock (msr -> modsecurity -> dbm_lock );
216+ if (rc != APR_SUCCESS ) {
217+ msr_log (msr , 1 , "collection_retrieve_ex: Failed to lock proc mutex: %s" ,
218+ get_apr_error (msr -> mp , rc ));
219+ goto cleanup ;
220+ }
205221 rc = apr_sdbm_open (& dbm , dbm_filename , APR_CREATE | APR_WRITE | APR_SHARELOCK ,
206222 CREATEMODE , msr -> mp );
207223 if (rc != APR_SUCCESS ) {
208224 msr_log (msr , 1 , "collection_retrieve_ex: Failed to access DBM file \"%s\": %s" ,
209225 log_escape (msr -> mp , dbm_filename ), get_apr_error (msr -> mp , rc ));
210226 dbm = NULL ;
227+ apr_global_mutex_unlock (msr -> modsecurity -> dbm_lock );
211228 goto cleanup ;
212229 }
213230 }
@@ -230,6 +247,7 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
230247
231248 if (existing_dbm == NULL ) {
232249 apr_sdbm_close (dbm );
250+ apr_global_mutex_unlock (msr -> modsecurity -> dbm_lock );
233251 dbm = NULL ;
234252 }
235253
@@ -292,14 +310,16 @@ static apr_table_t *collection_retrieve_ex(apr_sdbm_t *existing_dbm, modsec_rec
292310 log_escape (msr -> mp , col_name ), log_escape_ex (msr -> mp , col_key , col_key_len ));
293311
294312 apr_sdbm_close (dbm );
313+ apr_global_mutex_unlock (msr -> modsecurity -> dbm_lock );
295314 }
296-
315+
297316 return col ;
298317
299318cleanup :
300319
301320 if ((existing_dbm == NULL ) && dbm ) {
302321 apr_sdbm_close (dbm );
322+ apr_global_mutex_unlock (msr -> modsecurity -> dbm_lock );
303323 }
304324
305325 return NULL ;
@@ -412,6 +432,14 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
412432 var -> value_len = strlen (var -> value );
413433 }
414434
435+ /* Need to lock to pull in the stored data again and apply deltas. */
436+ rc = apr_global_mutex_lock (msr -> modsecurity -> dbm_lock );
437+ if (rc != APR_SUCCESS ) {
438+ msr_log (msr , 1 , "collection_store: Failed to lock proc mutex: %s" ,
439+ get_apr_error (msr -> mp , rc ));
440+ goto error ;
441+ }
442+
415443 /* ENH Make the expiration timestamp accessible in blob form so that
416444 * it is easier/faster to determine expiration without having to
417445 * convert back to table form
@@ -420,19 +448,13 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
420448 rc = apr_sdbm_open (& dbm , dbm_filename , APR_CREATE | APR_WRITE | APR_SHARELOCK ,
421449 CREATEMODE , msr -> mp );
422450 if (rc != APR_SUCCESS ) {
451+ apr_global_mutex_unlock (msr -> modsecurity -> dbm_lock );
423452 msr_log (msr , 1 , "collection_store: Failed to access DBM file \"%s\": %s" , log_escape (msr -> mp , dbm_filename ),
424453 get_apr_error (msr -> mp , rc ));
425454 dbm = NULL ;
426455 goto error ;
427456 }
428-
429- /* Need to lock to pull in the stored data again and apply deltas. */
430- rc = apr_sdbm_lock (dbm , APR_FLOCK_EXCLUSIVE );
431- if (rc != APR_SUCCESS ) {
432- msr_log (msr , 1 , "collection_store: Failed to exclusivly lock DBM file \"%s\": %s" , log_escape (msr -> mp , dbm_filename ),
433- get_apr_error (msr -> mp , rc ));
434- goto error ;
435- }
457+
436458
437459 /* If there is an original value, then create a delta and
438460 * apply the delta to the current value */
@@ -497,8 +519,8 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
497519 blob = apr_pcalloc (msr -> mp , blob_size );
498520 if (blob == NULL ) {
499521 if (dbm != NULL ) {
500- apr_sdbm_unlock (dbm );
501522 apr_sdbm_close (dbm );
523+ apr_global_mutex_unlock (msr -> modsecurity -> dbm_lock );
502524 }
503525
504526 return -1 ;
@@ -555,16 +577,16 @@ int collection_store(modsec_rec *msr, apr_table_t *col) {
555577 msr_log (msr , 1 , "collection_store: Failed to write to DBM file \"%s\": %s" , dbm_filename ,
556578 get_apr_error (msr -> mp , rc ));
557579 if (dbm != NULL ) {
558- apr_sdbm_unlock (dbm );
559580 apr_sdbm_close (dbm );
581+ apr_global_mutex_unlock (msr -> modsecurity -> dbm_lock );
560582 }
561583
562584 return -1 ;
563585 }
564586
565- apr_sdbm_unlock (dbm );
566587 apr_sdbm_close (dbm );
567-
588+ apr_global_mutex_unlock (msr -> modsecurity -> dbm_lock );
589+
568590 if (msr -> txcfg -> debuglog_level >= 4 ) {
569591 msr_log (msr , 4 , "collection_store: Persisted collection (name \"%s\", key \"%s\")." ,
570592 log_escape_ex (msr -> mp , var_name -> value , var_name -> value_len ),
@@ -608,9 +630,17 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) {
608630 log_escape (msr -> mp , dbm_filename ));
609631 }
610632
633+ rc = apr_global_mutex_lock (msr -> modsecurity -> dbm_lock );
634+ if (rc != APR_SUCCESS ) {
635+ msr_log (msr , 1 , "collections_remove_stale: Failed to lock proc mutex: %s" ,
636+ get_apr_error (msr -> mp , rc ));
637+ goto error ;
638+ }
639+
611640 rc = apr_sdbm_open (& dbm , dbm_filename , APR_CREATE | APR_WRITE | APR_SHARELOCK ,
612641 CREATEMODE , msr -> mp );
613642 if (rc != APR_SUCCESS ) {
643+ apr_global_mutex_unlock (msr -> modsecurity -> dbm_lock );
614644 msr_log (msr , 1 , "collections_remove_stale: Failed to access DBM file \"%s\": %s" , log_escape (msr -> mp , dbm_filename ),
615645 get_apr_error (msr -> mp , rc ));
616646 dbm = NULL ;
@@ -619,12 +649,6 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) {
619649
620650 /* First get a list of all keys. */
621651 keys_arr = apr_array_make (msr -> mp , 256 , sizeof (char * ));
622- rc = apr_sdbm_lock (dbm , APR_FLOCK_SHARED );
623- if (rc != APR_SUCCESS ) {
624- msr_log (msr , 1 , "collections_remove_stale: Failed to lock DBM file \"%s\": %s" , log_escape (msr -> mp , dbm_filename ),
625- get_apr_error (msr -> mp , rc ));
626- goto error ;
627- }
628652
629653 /* No one can write to the file while doing this so
630654 * do it as fast as possible.
@@ -637,7 +661,6 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) {
637661 }
638662 rc = apr_sdbm_nextkey (dbm , & key );
639663 }
640- apr_sdbm_unlock (dbm );
641664
642665 if (msr -> txcfg -> debuglog_level >= 9 ) {
643666 msr_log (msr , 9 , "collections_remove_stale: Found %d record(s) in file \"%s\"." , keys_arr -> nelts ,
@@ -706,13 +729,14 @@ int collections_remove_stale(modsec_rec *msr, const char *col_name) {
706729 }
707730
708731 apr_sdbm_close (dbm );
709-
732+ apr_global_mutex_unlock ( msr -> modsecurity -> dbm_lock );
710733 return 1 ;
711734
712735error :
713736
714737 if (dbm ) {
715738 apr_sdbm_close (dbm );
739+ apr_global_mutex_unlock (msr -> modsecurity -> dbm_lock );
716740 }
717741
718742 return -1 ;
0 commit comments