summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2013-12-25 01:46:01 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2013-12-25 01:46:01 +0000
commit97d938ac0732544ba829e1bac7866c2e3dfd7e9e (patch)
treeb42c0eed6cc0b2c7cffa54a3044704a36a2a6121 /usr.bin
parenteb66be1009a902de97f4d2d776d681f8020ded7d (diff)
final circleq to tailq fix. restore the previous pointer check by reading
the previous value again and checking prev.next is still next. maybe ok guenther
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/netstat/inet.c11
-rw-r--r--usr.bin/systat/netstat.c15
-rw-r--r--usr.bin/tcpbench/tcpbench.c13
3 files changed, 33 insertions, 6 deletions
diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c
index 070c6da6334..b01b4d571be 100644
--- a/usr.bin/netstat/inet.c
+++ b/usr.bin/netstat/inet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: inet.c,v 1.128 2013/12/24 22:26:19 tedu Exp $ */
+/* $OpenBSD: inet.c,v 1.129 2013/12/25 01:46:00 tedu Exp $ */
/* $NetBSD: inet.c,v 1.14 1995/10/03 21:42:37 thorpej Exp $ */
/*
@@ -111,7 +111,7 @@ protopr(u_long off, char *name, int af, u_int tableid, u_long pcbaddr)
{
struct inpcbtable table;
struct inpcb *prev, *next;
- struct inpcb inpcb;
+ struct inpcb inpcb, prevpcb;
int istcp, israw, isany;
int addrlen = 22;
int first = 1;
@@ -129,6 +129,13 @@ protopr(u_long off, char *name, int af, u_int tableid, u_long pcbaddr)
while (next != NULL) {
kread((u_long)next, &inpcb, sizeof inpcb);
+ if (prev != NULL) {
+ kread((u_long)prev, &prevpcb, sizeof prevpcb);
+ if (TAILQ_NEXT(&prevpcb, inp_queue) != next) {
+ printf("PCB list changed\n");
+ break;
+ }
+ }
prev = next;
next = TAILQ_NEXT(&inpcb, inp_queue);
diff --git a/usr.bin/systat/netstat.c b/usr.bin/systat/netstat.c
index 3f4f38e2aeb..3bca253376e 100644
--- a/usr.bin/systat/netstat.c
+++ b/usr.bin/systat/netstat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netstat.c,v 1.38 2013/12/24 22:26:20 tedu Exp $ */
+/* $OpenBSD: netstat.c,v 1.39 2013/12/25 01:46:00 tedu Exp $ */
/* $NetBSD: netstat.c,v 1.3 1995/06/18 23:53:07 cgd Exp $ */
/*-
@@ -232,8 +232,8 @@ int
read_ns(void)
{
struct inpcbtable pcbtable;
- struct inpcb *next;
- struct inpcb inpcb;
+ struct inpcb *next, *prev;
+ struct inpcb inpcb, prevpcb;
struct socket sockb;
struct tcpcb tcpcb;
void *off;
@@ -262,10 +262,19 @@ read_ns(void)
again:
KREAD(off, &pcbtable, sizeof (struct inpcbtable));
+ prev = NULL;
next = TAILQ_FIRST(&pcbtable.inpt_queue);
while (next != NULL) {
KREAD(next, &inpcb, sizeof (inpcb));
+ if (prev != NULL) {
+ KREAD(prev, &prevpcb, sizeof (prevpcb));
+ if (TAILQ_NEXT(&prevpcb, inp_queue) != next) {
+ error("Kernel state in transition");
+ return 0;
+ }
+ }
+ prev = next;
next = TAILQ_NEXT(&inpcb, inp_queue);
if (!aflag) {
diff --git a/usr.bin/tcpbench/tcpbench.c b/usr.bin/tcpbench/tcpbench.c
index 6ae22ec7a42..43f59012ad1 100644
--- a/usr.bin/tcpbench/tcpbench.c
+++ b/usr.bin/tcpbench/tcpbench.c
@@ -291,7 +291,7 @@ kfind_tcb(int sock)
{
struct inpcbtable tcbtab;
struct inpcb *next, *prev;
- struct inpcb inpcb;
+ struct inpcb inpcb, prevpcb;
struct tcpcb tcpcb;
struct sockaddr_storage me, them;
@@ -331,6 +331,17 @@ retry:
if (ptb->vflag >= 2)
fprintf(stderr, "Checking PCB %p\n", next);
kget((u_long)next, &inpcb, sizeof(inpcb));
+ if (prev != NULL) {
+ kget((u_long)prev, &prevpcb, sizeof(prevpcb));
+ if (TAILQ_NEXT(&prevpcb, inp_queue) != next) {
+ if (nretry--) {
+ warnx("PCB prev pointer insane");
+ goto retry;
+ } else
+ errx(1, "PCB prev pointer insane,"
+ " all attempts exhaused");
+ }
+ }
prev = next;
next = TAILQ_NEXT(&inpcb, inp_queue);