Author: mav
Date: Tue Oct 13 17:50:01 2020
New Revision: 366675
URL: https://svnweb.freebsd.org/changeset/base/366675

Log:
  MFC r355083 (by rlibby): sysctl: 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.

Modified:
  stable/12/sys/kern/kern_sysctl.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/kern/kern_sysctl.c
==============================================================================
--- stable/12/sys/kern/kern_sysctl.c    Tue Oct 13 17:30:34 2020        
(r366674)
+++ stable/12/sys/kern/kern_sysctl.c    Tue Oct 13 17:50:01 2020        
(r366675)
@@ -1022,12 +1022,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) {
@@ -1264,6 +1268,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)
@@ -1293,6 +1301,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)
@@ -1317,6 +1329,10 @@ sysctl_sysctl_oidlabel(SYSCTL_HANDLER_ARGS)
        struct sysctl_oid *oid;
        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);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to