This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2] Make fmtmsg() function to multithread-safe


fmtmsg() uses a static variables severity_list which is not protected. It is
not safe in multithread circumstance.

When call fmtmsg() and addseverity() simultaneously in multithread circumstance,
the following case will cause unsafe. The case has two threads: A and B.

a. thread B call addseverity(5, "TEST_FMTMSG")
b. thread A call fmtmsg(classification, NULL, 5, NULL, NULL, NULL), when search
   severity, but not output error message
   code:	 if (severity == severity_rec->severity)
c. thread B call addseverity(5, NULL)
d. thread A output error message to the given severity

Signed-off-by: Peng Haitao <penght@cn.fujitsu.com>
---
v1->v2: Initialize pstring to NULL

 ChangeLog       |    4 ++++
 stdlib/fmtmsg.c |   12 ++++++++++--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 73e51dc..cee48e9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2012-02-22  Peng Haitao  <penght@cn.fujitsu.com>
+
+	* stdlib/fmtmsg.c: Add lock to protect static variable.
+
 2012-02-20  David S. Miller  <davem@davemloft.net>
 
 	* sysdeps/sparc/sparc32/__longjmp.S: Unwind in the 'thread' path
diff --git a/stdlib/fmtmsg.c b/stdlib/fmtmsg.c
index 9203317..b012ed8 100644
--- a/stdlib/fmtmsg.c
+++ b/stdlib/fmtmsg.c
@@ -105,6 +105,7 @@ fmtmsg (long int classification, const char *label, int severity,
   __libc_once_define (static, once);
   int result = MM_OK;
   struct severity_info *severity_rec;
+  const char *pstring = NULL;
 
   /* Make sure everything is initialized.  */
   __libc_once (once, init);
@@ -124,11 +125,18 @@ fmtmsg (long int classification, const char *label, int severity,
 	return MM_NOTOK;
     }
 
+  __libc_lock_lock (lock);
+
   for (severity_rec = severity_list; severity_rec != NULL;
        severity_rec = severity_rec->next)
     if (severity == severity_rec->severity)
+    {
+      pstring = severity_rec->string;
       /* Bingo.  */
       break;
+    }
+
+  __libc_lock_unlock (lock);
 
   /* If we don't know anything about the severity level return an error.  */
   if (severity_rec == NULL)
@@ -156,7 +164,7 @@ fmtmsg (long int classification, const char *label, int severity,
 		      do_label ? label : "",
 		      do_label && (do_severity | do_text | do_action | do_tag)
 		      ? ": " : "",
-		      do_severity ? severity_rec->string : "",
+		      do_severity ? pstring : "",
 		      do_severity && (do_text | do_action | do_tag)
 		      ? ": " : "",
 		      do_text ? text : "",
@@ -181,7 +189,7 @@ fmtmsg (long int classification, const char *label, int severity,
 	      do_label ? label : "",
 	      do_label && (do_severity | do_text | do_action | do_tag)
 	      ? ": " : "",
-	      do_severity ? severity_rec->string : "",
+	      do_severity ? pstring : "",
 	      do_severity && (do_text | do_action | do_tag) ? ": " : "",
 	      do_text ? text : "",
 	      do_text && (do_action | do_tag) ? "\n" : "",
-- 
1.7.1

-- 
Best Regards,
Peng


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]