comparison lib/regcomp.c @ 17419:020c917cba9d

regex: fix dfa race in multithreaded uses Problem reported by Ludovic Courtès in <http://lists.gnu.org/archive/html/bug-gnulib/2013-05/msg00058.html>. * lib/regex_internal.h (lock_define, lock_init, lock_fini): New macros. All uses of __libc_lock_define, __libc_lock_init changed to use the first two of these. (__libc_lock_lock, __libc_lock_unlock): New macros, for non-glibc platforms. (struct re_dfa_t): Define the lock unconditionally. * lib/regexec.c (regexec, re_search_stub): Remove some now-incorrect '#ifdef _LIBC"s. * modules/regex (Depends-on): Add pthread, if we use the included regex. * lib/regcomp.c: Do actions that are not needed for glibc, but may be needed elsewhere. (regfree, re_compile_internal): Destroy the lock. (re_compile_internal): Check for lock-initialization failure.
author Paul Eggert <eggert@cs.ucla.edu>
date Sun, 19 May 2013 14:26:05 -0700
parents cd38818bce4e
children 6105f1dfb98e
comparison
equal deleted inserted replaced
17418:b876bfd31d0f 17419:020c917cba9d
661 regfree (preg) 661 regfree (preg)
662 regex_t *preg; 662 regex_t *preg;
663 { 663 {
664 re_dfa_t *dfa = preg->buffer; 664 re_dfa_t *dfa = preg->buffer;
665 if (BE (dfa != NULL, 1)) 665 if (BE (dfa != NULL, 1))
666 free_dfa_content (dfa); 666 {
667 lock_fini (dfa->lock);
668 free_dfa_content (dfa);
669 }
667 preg->buffer = NULL; 670 preg->buffer = NULL;
668 preg->allocated = 0; 671 preg->allocated = 0;
669 672
670 re_free (preg->fastmap); 673 re_free (preg->fastmap);
671 preg->fastmap = NULL; 674 preg->fastmap = NULL;
782 preg->buffer = dfa; 785 preg->buffer = dfa;
783 } 786 }
784 preg->used = sizeof (re_dfa_t); 787 preg->used = sizeof (re_dfa_t);
785 788
786 err = init_dfa (dfa, length); 789 err = init_dfa (dfa, length);
790 if (BE (err == REG_NOERROR && lock_init (dfa->lock) != 0, 0))
791 err = REG_ESPACE;
787 if (BE (err != REG_NOERROR, 0)) 792 if (BE (err != REG_NOERROR, 0))
788 { 793 {
789 free_dfa_content (dfa); 794 free_dfa_content (dfa);
790 preg->buffer = NULL; 795 preg->buffer = NULL;
791 preg->allocated = 0; 796 preg->allocated = 0;
795 /* Note: length+1 will not overflow since it is checked in init_dfa. */ 800 /* Note: length+1 will not overflow since it is checked in init_dfa. */
796 dfa->re_str = re_malloc (char, length + 1); 801 dfa->re_str = re_malloc (char, length + 1);
797 strncpy (dfa->re_str, pattern, length + 1); 802 strncpy (dfa->re_str, pattern, length + 1);
798 #endif 803 #endif
799 804
800 __libc_lock_init (dfa->lock);
801
802 err = re_string_construct (&regexp, pattern, length, preg->translate, 805 err = re_string_construct (&regexp, pattern, length, preg->translate,
803 (syntax & RE_ICASE) != 0, dfa); 806 (syntax & RE_ICASE) != 0, dfa);
804 if (BE (err != REG_NOERROR, 0)) 807 if (BE (err != REG_NOERROR, 0))
805 { 808 {
806 re_compile_internal_free_return: 809 re_compile_internal_free_return:
807 free_workarea_compile (preg); 810 free_workarea_compile (preg);
808 re_string_destruct (&regexp); 811 re_string_destruct (&regexp);
812 lock_fini (dfa->lock);
809 free_dfa_content (dfa); 813 free_dfa_content (dfa);
810 preg->buffer = NULL; 814 preg->buffer = NULL;
811 preg->allocated = 0; 815 preg->allocated = 0;
812 return err; 816 return err;
813 } 817 }
836 free_workarea_compile (preg); 840 free_workarea_compile (preg);
837 re_string_destruct (&regexp); 841 re_string_destruct (&regexp);
838 842
839 if (BE (err != REG_NOERROR, 0)) 843 if (BE (err != REG_NOERROR, 0))
840 { 844 {
845 lock_fini (dfa->lock);
841 free_dfa_content (dfa); 846 free_dfa_content (dfa);
842 preg->buffer = NULL; 847 preg->buffer = NULL;
843 preg->allocated = 0; 848 preg->allocated = 0;
844 } 849 }
845 850