From 2537beac64567fee2e1bce326e713a4b48960ca9 Mon Sep 17 00:00:00 2001 From: mvs Date: Wed, 26 May 2021 08:28:34 +0000 Subject: [PATCH] Use `so_lock' to protect key management (PF_KEY) sockets. This can be done because we have no cases where one thread should lock two sockets simultaneously. tested by yasuoka@ ok bluhm@ markus@ --- sys/kern/uipc_socket2.c | 26 +++++--------------------- sys/net/pfkeyv2.c | 13 +++++++++++-- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 851a0dfa16d..07ecd09627d 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket2.c,v 1.109 2021/05/01 16:13:13 mvs Exp $ */ +/* $OpenBSD: uipc_socket2.c,v 1.110 2021/05/26 08:28:34 mvs Exp $ */ /* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */ /* @@ -287,12 +287,8 @@ solock(struct socket *so) case PF_UNIX: rw_enter_write(&unp_lock); break; - case PF_ROUTE: - rw_enter_write(&so->so_lock); - break; - case PF_KEY: default: - KERNEL_LOCK(); + rw_enter_write(&so->so_lock); break; } @@ -315,12 +311,8 @@ sounlock(struct socket *so, int s) case PF_UNIX: rw_exit_write(&unp_lock); break; - case PF_ROUTE: - rw_exit_write(&so->so_lock); - break; - case PF_KEY: default: - KERNEL_UNLOCK(); + rw_exit_write(&so->so_lock); break; } } @@ -336,12 +328,8 @@ soassertlocked(struct socket *so) case PF_UNIX: rw_assert_wrlock(&unp_lock); break; - case PF_ROUTE: - rw_assert_wrlock(&so->so_lock); - break; - case PF_KEY: default: - KERNEL_ASSERT_LOCKED(); + rw_assert_wrlock(&so->so_lock); break; } } @@ -360,12 +348,8 @@ sosleep_nsec(struct socket *so, void *ident, int prio, const char *wmesg, case PF_UNIX: ret = rwsleep_nsec(ident, &unp_lock, prio, wmesg, nsecs); break; - case PF_ROUTE: - ret = rwsleep_nsec(ident, &so->so_lock, prio, wmesg, nsecs); - break; - case PF_KEY: default: - ret = tsleep_nsec(ident, prio, wmesg, nsecs); + ret = rwsleep_nsec(ident, &so->so_lock, prio, wmesg, nsecs); break; } diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c index fa6917352b5..0152df93eda 100644 --- a/sys/net/pfkeyv2.c +++ b/sys/net/pfkeyv2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2.c,v 1.213 2021/05/25 22:45:09 bluhm Exp $ */ +/* $OpenBSD: pfkeyv2.c,v 1.214 2021/05/26 08:28:34 mvs Exp $ */ /* * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 @@ -246,7 +246,7 @@ pfkey_init(void) rw_init(&pkptable.pkp_lk, "pfkey"); SRPL_INIT(&pkptable.pkp_list); pool_init(&pkpcb_pool, sizeof(struct pkpcb), 0, - IPL_NONE, PR_WAITOK, "pkpcb", NULL); + IPL_SOFTNET, PR_WAITOK, "pkpcb", NULL); pool_init(&ipsec_policy_pool, sizeof(struct ipsec_policy), 0, IPL_SOFTNET, 0, "ipsec policy", NULL); } @@ -315,8 +315,10 @@ pfkeyv2_detach(struct socket *so) kcb_list); rw_exit(&pkptable.pkp_lk); + sounlock(so, SL_LOCKED); /* wait for all references to drop */ refcnt_finalize(&kp->kcb_refcnt, "pfkeyrefs"); + solock(so); so->so_pcb = NULL; KASSERT((so->so_state & SS_NOFDREF) == 0); @@ -430,7 +432,14 @@ pfkeyv2_output(struct mbuf *mbuf, struct socket *so, m_copydata(mbuf, 0, mbuf->m_pkthdr.len, message); + /* + * The socket can't be closed concurrently because the file + * descriptor reference is still held. + */ + + sounlock(so, SL_LOCKED); error = pfkeyv2_send(so, message, mbuf->m_pkthdr.len); + solock(so); ret: m_freem(mbuf); -- 2.20.1