Subject: bin/3285: dmesg sometimes fall into infinite loop
To: None <gnats-bugs@gnats.netbsd.org>
From: None <enami@ba2.so-net.or.jp>
List: netbsd-bugs
Date: 03/03/1997 22:15:41
>Number: 3285
>Category: bin
>Synopsis: dmesg sometimes fall into infinite loop
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Mar 3 06:20:07 1997
>Last-Modified:
>Originator: enami tsugutomo
>Organization:
An individual
>Release: NetBSD-current 1997 Mar 01
>Environment:
System: NetBSD pavlov.enami.ba2.so-net.or.jp 1.2C NetBSD 1.2C (PAVLOV) #164: Sat Feb 8 01:00:12 JST 1997 enami@pavlov.enami.ba2.so-net.or.jp:/b/netbsd/kernel/compile/PAVLOV i386
>Description:
The command dmesg sometimes fall into infinit loop. I
observed it when (pointer to msgbuf)->msg_bufx is one.
Probably it occurs when it is zero.
Here is a piece of code quoted from dmesg.c:
p = cur.msg_bufc + cur.msg_bufx;
ep = cur.msg_bufc + cur.msg_bufx - 1;
for (newl = skip = 0; p != ep; ++p) {
if (p == cur.msg_bufc + MSG_BSIZE)
p = cur.msg_bufc;
ch = *p;
In above code, when testing `p != ep', variable `p' will have
a value of range between cur.msg_bufc + 1 and cur.msg_bufc +
MSG_BSIZE (except the frist test which always fails). But
variable `ep' will have a value of range between cur.msg_bufc
- 1 and cur.msg_bufc + MSG_BSIZE - 1.
Then, it is obvious that if cur.msg_bufx is zero or one, the
loop never exits.
>How-To-Repeat:
Call dmesg when (pointer to msgbuf)->msg_bufx is one.
>Fix:
Here is a patch I'm currenty using.
Index: dmesg.c
===================================================================
RCS file: /a/cvsroot/NetBSD/src/sbin/dmesg/dmesg.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 dmesg.c
--- dmesg.c 1996/11/16 10:06:41 1.1.1.1
+++ dmesg.c 1997/02/22 15:18:09
@@ -126,10 +126,10 @@
* The message buffer is circular; start at the read pointer, and
* go to the write pointer - 1.
*/
- p = cur.msg_bufc + cur.msg_bufx;
- ep = cur.msg_bufc + cur.msg_bufx - 1;
- for (newl = skip = 0; p != ep; ++p) {
- if (p == cur.msg_bufc + MSG_BSIZE)
+ p = ep = cur.msg_bufc + (cur.msg_bufx - 1 + MSG_BSIZE) % MSG_BSIZE;
+ newl = skip = 0;
+ do {
+ if (++p == cur.msg_bufc + MSG_BSIZE)
p = cur.msg_bufc;
ch = *p;
/* Skip "\n<.*>" syslog sequences. */
@@ -150,7 +150,7 @@
(void)putchar(buf[0]);
else
(void)printf("%s", buf);
- }
+ } while (p != ep);
if (!newl)
(void)putchar('\n');
exit(0);
>Audit-Trail:
>Unformatted: