From 7bd231952ea03c3bf6ebb78f49ca290c33520c92 Mon Sep 17 00:00:00 2001 From: itojun Date: Mon, 31 May 2004 04:29:01 +0000 Subject: [PATCH] safer key_{spd,}dump. comment from yamt. XXX is spl level ok? --- sys/netkey/key.c | 28 ++++++++++++++++++++++------ sys/netkey/keysock.c | 11 ++++++----- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/sys/netkey/key.c b/sys/netkey/key.c index 4dc755790444..df4b96528051 100644 --- a/sys/netkey/key.c +++ b/sys/netkey/key.c @@ -1,4 +1,4 @@ -/* $NetBSD: key.c,v 1.120 2004/05/26 02:59:15 itojun Exp $ */ +/* $NetBSD: key.c,v 1.121 2004/05/31 04:29:01 itojun Exp $ */ /* $KAME: key.c,v 1.310 2003/09/08 02:23:44 itojun Exp $ */ /* @@ -35,7 +35,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.120 2004/05/26 02:59:15 itojun Exp $"); +__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.121 2004/05/31 04:29:01 itojun Exp $"); #include "opt_inet.h" #include "opt_ipsec.h" @@ -2307,6 +2307,8 @@ key_spddump(so, m, mhp) int cnt; u_int dir; struct mbuf *n; + struct keycb *kp; + int error = 0, needwait = 0; /* sanity check */ if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL) @@ -2329,12 +2331,19 @@ key_spddump(so, m, mhp) n = key_setdumpsp(sp, SADB_X_SPDDUMP, cnt, mhp->msg->sadb_msg_pid); - if (n) - key_sendup_mbuf(so, n, + if (n) { + error = key_sendup_mbuf(so, n, KEY_SENDUP_ONE | KEY_SENDUP_CANWAIT); + if (error == EAGAIN) + needwait = 1; + } } } + kp = (struct keycb *)sotorawcb(so); + while (needwait && kp->kp_queue) + sbwait(&so->so_rcv); + m_freem(m); return 0; } @@ -6757,7 +6766,8 @@ key_dump(so, m, mhp) u_int stateidx; u_int8_t satype; u_int8_t state; - int cnt; + int cnt, error = 0, needwait = 0; + struct keycb *kp; struct mbuf *n; /* sanity check */ @@ -6812,12 +6822,18 @@ key_dump(so, m, mhp) if (!n) return key_senderror(so, m, ENOBUFS); - key_sendup_mbuf(so, n, + error = key_sendup_mbuf(so, n, KEY_SENDUP_ONE | KEY_SENDUP_CANWAIT); + if (error == EAGAIN) + needwait = 1; } } } + kp = (struct keycb *)sotorawcb(so); + while (needwait && kp->kp_queue) + sbwait(&so->so_rcv); + m_freem(m); return 0; } diff --git a/sys/netkey/keysock.c b/sys/netkey/keysock.c index 0ecad9c9dcca..d283603b2ec9 100644 --- a/sys/netkey/keysock.c +++ b/sys/netkey/keysock.c @@ -1,4 +1,4 @@ -/* $NetBSD: keysock.c,v 1.30 2004/05/26 02:59:15 itojun Exp $ */ +/* $NetBSD: keysock.c,v 1.31 2004/05/31 04:29:01 itojun Exp $ */ /* $KAME: keysock.c,v 1.32 2003/08/22 05:45:08 itojun Exp $ */ /* @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.30 2004/05/26 02:59:15 itojun Exp $"); +__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.31 2004/05/31 04:29:01 itojun Exp $"); #include "opt_inet.h" @@ -268,8 +268,10 @@ key_sendup0(rp, m, promisc, canwait) } if (canwait && - sbspace(&rp->rcb_socket->so_rcv) < m->m_pkthdr.len) - sbwait(&rp->rcb_socket->so_rcv); + sbspace(&rp->rcb_socket->so_rcv) < m->m_pkthdr.len) { + error = EAGAIN; + continue; + } if (!sbappendaddr(&rp->rcb_socket->so_rcv, (struct sockaddr *)&key_src, m, NULL)) { @@ -278,7 +280,6 @@ key_sendup0(rp, m, promisc, canwait) error = ENOBUFS; } else error = 0; - sorwakeup(rp->rcb_socket); } return error; }