sysctl sysctls: wire old buf before output with sysctl lock

Several sysctl sysctls output to a user buffer while holding a
non-sleepable lock that protects the sysctl topology.  They need to wire
the output buffer, or else they may try to sleep on a page fault.

Reviewed by:	cem, markj
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D22528
This commit is contained in:
Ryan Libby 2019-11-25 07:38:27 +00:00
parent 4d987866e6
commit 43cefe8b19

View file

@ -1023,12 +1023,16 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
{
int *name = (int *) arg1;
u_int namelen = arg2;
int error = 0;
int error;
struct sysctl_oid *oid;
struct sysctl_oid_list *lsp = &sysctl__children, *lsp2;
struct rm_priotracker tracker;
char buf[10];
error = sysctl_wire_old_buffer(req, 0);
if (error)
return (error);
SYSCTL_RLOCK(&tracker);
while (namelen) {
if (!lsp) {
@ -1265,6 +1269,10 @@ sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
struct rm_priotracker tracker;
int error;
error = sysctl_wire_old_buffer(req, 0);
if (error)
return (error);
SYSCTL_RLOCK(&tracker);
error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
if (error)
@ -1294,6 +1302,10 @@ sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS)
struct rm_priotracker tracker;
int error;
error = sysctl_wire_old_buffer(req, 0);
if (error)
return (error);
SYSCTL_RLOCK(&tracker);
error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
if (error)
@ -1319,6 +1331,10 @@ sysctl_sysctl_oidlabel(SYSCTL_HANDLER_ARGS)
struct rm_priotracker tracker;
int error;
error = sysctl_wire_old_buffer(req, 0);
if (error)
return (error);
SYSCTL_RLOCK(&tracker);
error = sysctl_find_oid(arg1, arg2, &oid, NULL, req);
if (error)