summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_divert.c
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2022-05-09 19:33:47 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2022-05-09 19:33:47 +0000
commitb2815671552874de4462af758bc1d6e24bf66fbd (patch)
tree0894a7cd6bd73e7e72c73e09bad6c7d934136a45 /sys/netinet/ip_divert.c
parenta833eb4b8074f358bd3e637c07d2825d53e25bb8 (diff)
Protect sbappendaddr() in divert_packet() with kernel lock. With
divert-packet rules pf calls directly from IP layer to protocol layer. As the former has only shared net lock, additional protection against parallel access is needed. Kernel lock is a temporary workaround until the socket layer is MP safe. discussed with kettenis@ mvs@
Diffstat (limited to 'sys/netinet/ip_divert.c')
-rw-r--r--sys/netinet/ip_divert.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 187bbe8c96c..aae4ed62bea 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_divert.c,v 1.67 2022/05/05 16:44:22 bluhm Exp $ */
+/* $OpenBSD: ip_divert.c,v 1.68 2022/05/09 19:33:46 bluhm Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -222,11 +222,19 @@ divert_packet(struct mbuf *m, int dir, u_int16_t divert_port)
}
so = inp->inp_socket;
+ /*
+ * XXXSMP sbappendaddr() is not MP safe and this function is called
+ * from pf with shared netlock. To call only one sbappendaddr() from
+ * divert_packet(), protect it with kernel lock. All other places
+ * call sbappendaddr() with exclusive net lock. This blocks
+ * divert_packet() as we have the shared lock.
+ */
+ KERNEL_LOCK();
if (sbappendaddr(so, &so->so_rcv, sintosa(&sin), m, NULL) == 0) {
+ KERNEL_UNLOCK();
divstat_inc(divs_fullsock);
goto bad;
}
- KERNEL_LOCK();
sorwakeup(inp->inp_socket);
KERNEL_UNLOCK();