Looking at users of the global interface list `ifnetlist', drivers like
this read out an IP or MAC address to report to the hypervisor.

None of this modifies any of the fields in the global list, they
iterate over and read from it.

net/if_var.h documents the `if_list' member as kernel lock protected,
but I think this is no longer true -- there are drivers solely relying
on the net lock for it, see vmt(4) or mld6_fasttimeo().

So as a start, treat the exclusive kernel lock for a shared net lock
which currently protects the list.

The current kernel lock was added in 2016 with the initial code in
r1.9 "Handle IP address information requests".

Did I miss anything?

Can somebody run this on a Generation 1 Virtual Machine for me?
I don't have access to HyperV.

diff --git a/sys/dev/pv/hypervic.c b/sys/dev/pv/hypervic.c
index 9c7f70dd96f..02a67c162fc 100644
--- a/sys/dev/pv/hypervic.c
+++ b/sys/dev/pv/hypervic.c
@@ -870,7 +870,7 @@ kvp_get_ip_info(struct hv_kvp *kvp, const uint8_t *mac, 
uint8_t *family,
                return (-1);
        }
 
-       KERNEL_LOCK();
+       NET_LOCK_SHARED();
        s = splnet();
 
        TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
@@ -879,7 +879,7 @@ kvp_get_ip_info(struct hv_kvp *kvp, const uint8_t *mac, 
uint8_t *family,
        }
        if (ifp == NULL) {
                splx(s);
-               KERNEL_UNLOCK();
+               NET_UNLOCK_SHARED();
                return (-1);
        }
 
@@ -920,7 +920,7 @@ kvp_get_ip_info(struct hv_kvp *kvp, const uint8_t *mac, 
uint8_t *family,
                        ifa = ifa6ll;
                else {
                        splx(s);
-                       KERNEL_UNLOCK();
+                       NET_UNLOCK_SHARED();
                        return (-1);
                }
        }
@@ -957,7 +957,7 @@ kvp_get_ip_info(struct hv_kvp *kvp, const uint8_t *mac, 
uint8_t *family,
        }
 
        splx(s);
-       KERNEL_UNLOCK();
+       NET_UNLOCK_SHARED();
 
        return (0);
 }

Reply via email to