Call pfkeyv2_sysctl_policydumper() with shared netlock. It performs
authormvs <mvs@openbsd.org>
Sat, 22 Apr 2023 20:51:56 +0000 (20:51 +0000)
committermvs <mvs@openbsd.org>
Sat, 22 Apr 2023 20:51:56 +0000 (20:51 +0000)
read-olny access to netlock protected data, so the radix tree will
not be modified during spd_table_walk() run.

Also change netlock assertion within spd_table_add() and
ipsec_delete_policy() to exclusive. These are correlating functions
which modifies radix tree, so make us sure spd_table_walk() run with
shared netlock is safe.

Feedback and ok by bluhm@

sys/net/pfkeyv2.c
sys/netinet/ip_spd.c

index 4aab053..cdc5ce2 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2.c,v 1.255 2023/01/08 10:26:36 mvs Exp $ */
+/* $OpenBSD: pfkeyv2.c,v 1.256 2023/04/22 20:51:56 mvs Exp $ */
 
 /*
  *     @(#)COPYRIGHT   1.1 (NRL) 17 January 1995
@@ -2711,10 +2711,10 @@ pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
                break;
 
        case NET_KEY_SPD_DUMP:
-               NET_LOCK();
+               NET_LOCK_SHARED();
                error = spd_table_walk(rdomain,
                    pfkeyv2_sysctl_policydumper, &w);
-               NET_UNLOCK();
+               NET_UNLOCK_SHARED();
                if (oldp)
                        *oldlenp = w.w_where - oldp;
                else
index 48cfb04..1d40979 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_spd.c,v 1.117 2022/06/17 13:40:21 bluhm Exp $ */
+/* $OpenBSD: ip_spd.c,v 1.118 2023/04/22 20:51:56 mvs Exp $ */
 /*
  * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
  *
@@ -90,7 +90,7 @@ spd_table_add(unsigned int rtableid)
        unsigned int rdomain;
        void *p;
 
-       NET_ASSERT_LOCKED();
+       NET_ASSERT_LOCKED_EXCLUSIVE();
 
        rdomain = rtable_l2(rtableid);
        if (spd_tables == NULL || rdomain > spd_table_max) {
@@ -673,7 +673,7 @@ ipsec_delete_policy(struct ipsec_policy *ipo)
        struct radix_node_head *rnh;
        struct radix_node *rn = (struct radix_node *)ipo;
 
-       NET_ASSERT_LOCKED();
+       NET_ASSERT_LOCKED_EXCLUSIVE();
 
        if (refcnt_rele(&ipo->ipo_refcnt) == 0)
                return 0;