DF-0757 / fix.diff
diff --git a/sys/net/if_mib.c b/sys/net/if_mib.c --- a/sys/net/if_mib.c +++ b/sys/net/if_mib.c @@ -130,16 +130,29 @@ ifmd.ifmd_snd_drops = ifp->if_snd.ifq_drops; #endif + /* + * DF-0757: don't hold the global ifnet_lock across user + * copyin/copyout (may fault/sleep). ifmd is a complete local + * snapshot; drop the lock for the user copies, then re-acquire + * and revalidate before writing back. + */ + ifnet_unlock(); + error = SYSCTL_OUT(req, &ifmd, sizeof ifmd); if (error || !req->newptr) { - ifnet_unlock(); return error; } error = SYSCTL_IN(req, &ifmd, sizeof ifmd); if (error) { + return error; + } + + ifnet_lock(); + if (name[0] <= 0 || name[0] > if_index || + ifindex2ifnet[name[0]] != ifp) { ifnet_unlock(); - return error; + return ENOENT; } #define DONTCOPY(fld) ifmd.ifmd_data.ifi_##fld = ifp->if_data.ifi_##fld |