summaryrefslogtreecommitdiff
path: root/lib/libpthread/pthread_debug.c
diff options
context:
space:
mode:
authornathanw <nathanw@NetBSD.org>2003-06-16 21:24:48 +0000
committernathanw <nathanw@NetBSD.org>2003-06-16 21:24:48 +0000
commit876d7e7eec7ff50d22bfa192a8d943c2929f5d4c (patch)
tree1cab04d8b20c222ab5b75ae295638b74444b1dac /lib/libpthread/pthread_debug.c
parent18439070c7f39c233e548a1fe93a2910aa8a3c23 (diff)
Dodge a potential race condition in pthread__debuglog_printf(). It's
still possible for multiple threads to write into the same space, but they shouldn't be able to corrupt the write pointer in the process. Also, check for pointer-lapping a bit more carefully in the wrap vs. non-wrap case.
Diffstat (limited to 'lib/libpthread/pthread_debug.c')
-rw-r--r--lib/libpthread/pthread_debug.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/lib/libpthread/pthread_debug.c b/lib/libpthread/pthread_debug.c
index dd5ebbd5cde..66189d99ebe 100644
--- a/lib/libpthread/pthread_debug.c
+++ b/lib/libpthread/pthread_debug.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_debug.c,v 1.5 2003/04/16 17:37:47 nathanw Exp $ */
+/* $NetBSD: pthread_debug.c,v 1.6 2003/06/16 21:24:48 nathanw Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_debug.c,v 1.5 2003/04/16 17:37:47 nathanw Exp $");
+__RCSID("$NetBSD: pthread_debug.c,v 1.6 2003/06/16 21:24:48 nathanw Exp $");
#include <err.h>
#include <errno.h>
@@ -137,7 +137,7 @@ void
pthread__debuglog_printf(const char *fmt, ...)
{
char tmpbuf[200];
- size_t len, cplen;
+ size_t len, cplen, r, w, s;
long diff1, diff2;
va_list ap;
@@ -147,27 +147,38 @@ pthread__debuglog_printf(const char *fmt, ...)
va_start(ap, fmt);
len = vsnprintf(tmpbuf, 200, fmt, ap);
va_end(ap);
+
+ r = debugbuf->msg_bufr;
+ w = debugbuf->msg_bufw;
+ s = debugbuf->msg_bufs;
+ diff1 = (long)w - (long)r;
- diff1 = (long)debugbuf->msg_bufw - (long)debugbuf->msg_bufr;
-
- if (debugbuf->msg_bufw + len >= debugbuf->msg_bufs) {
- cplen = debugbuf->msg_bufs - debugbuf->msg_bufw;
- (void)memcpy(&debugbuf->msg_bufc[debugbuf->msg_bufw],
+ if (w + len >= s) {
+ cplen = s - w;
+ debugbuf->msg_bufw = len - cplen;
+ (void)memcpy(&debugbuf->msg_bufc[w],
tmpbuf, cplen);
(void)memcpy(&debugbuf->msg_bufc[0], tmpbuf + cplen,
len - cplen);
- debugbuf->msg_bufw = len - cplen;
+ w = len - cplen;
+
+ /* Check for lapping the read pointer. */
+ diff2 = (long)w - (long)r;
+ if (((diff1 < 0) && (diff2 <= 0)) ||
+ ((diff1 > 0) && (diff2 >= 0)))
+ debugbuf->msg_bufr = (w + 1) % s;
} else {
- (void)memcpy(&debugbuf->msg_bufc[debugbuf->msg_bufw],
+ debugbuf->msg_bufw = w + len;
+ (void)memcpy(&debugbuf->msg_bufc[w],
tmpbuf, len);
- debugbuf->msg_bufw += len;
+ w += len;
+
+ /* Check for lapping the read pointer. */
+ diff2 = (long)w - (long)r;
+ if ((diff1 < 0) && (diff2 >= 0))
+ debugbuf->msg_bufr = (w + 1) % s;
}
- diff2 = (long)debugbuf->msg_bufw - (long)debugbuf->msg_bufr;
-
- /* Check if we've lapped the read pointer and if so advance it. */
- if (((diff1 < 0) && (diff2 >= 0)) || ((diff1 >= 0) && (diff2 < 0)))
- debugbuf->msg_bufr = debugbuf->msg_bufw;
}
#endif