Author: kp
Date: Wed Apr 24 14:08:16 2019
New Revision: 346636
URL: https://svnweb.freebsd.org/changeset/base/346636

Log:
  MFC r346319:
  
  pf: Fix panic on invalid DIOCRSETTFLAGS
  
  If during DIOCRSETTFLAGS pfrio_buffer is NULL copyin() will fault, which we're
  not allowed to do with a lock held.
  We must count the number of entries in the table and release the lock during
  copyin(). Only then can we re-acquire the lock. Note that this is safe, 
because
  pfr_set_tflags() will check if the table and entries exist.
  
  This was discovered by a local syzcaller instance.

Modified:
  stable/11/sys/netpfil/pf/pf_ioctl.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/netpfil/pf/pf_ioctl.c
==============================================================================
--- stable/11/sys/netpfil/pf/pf_ioctl.c Wed Apr 24 14:08:14 2019        
(r346635)
+++ stable/11/sys/netpfil/pf/pf_ioctl.c Wed Apr 24 14:08:16 2019        
(r346636)
@@ -2686,24 +2686,24 @@ DIOCCHANGEADDR_error:
                        break;
                }
 
-               PF_RULES_WLOCK();
+               PF_RULES_RLOCK();
                n = pfr_table_count(&io->pfrio_table, io->pfrio_flags);
                io->pfrio_size = min(io->pfrio_size, n);
+               PF_RULES_RUNLOCK();
 
                totlen = io->pfrio_size * sizeof(struct pfr_table);
                pfrts = mallocarray(io->pfrio_size, sizeof(struct pfr_table),
                    M_TEMP, M_NOWAIT);
                if (pfrts == NULL) {
                        error = ENOMEM;
-                       PF_RULES_WUNLOCK();
                        break;
                }
                error = copyin(io->pfrio_buffer, pfrts, totlen);
                if (error) {
                        free(pfrts, M_TEMP);
-                       PF_RULES_WUNLOCK();
                        break;
                }
+               PF_RULES_WLOCK();
                error = pfr_set_tflags(pfrts, io->pfrio_size,
                    io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange,
                    &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
_______________________________________________
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