On Thu, Jul 21, 2022 at 11:13:28AM +0200, Moritz Buhl wrote:
> Hi tech,
> 
> for the other two DIOCX ioctls syzkaller showed that it is possible
> to grab netlock while doing copyin.
> 
> The same problem should exist for DIOCXCOMMIT but syzkaller didn't
> find it yet.
> 
> In case anybody can reproduce the witness lock order reversals the
> syzkaller can produce, the diff below might address the problem.
> 
> mbuhl

OK bluhm@

> Index: sys/net/pf_ioctl.c
> ===================================================================
> RCS file: /cvs/src/sys/net/pf_ioctl.c,v
> retrieving revision 1.383
> diff -u -p -r1.383 pf_ioctl.c
> --- sys/net/pf_ioctl.c        20 Jul 2022 09:33:11 -0000      1.383
> +++ sys/net/pf_ioctl.c        20 Jul 2022 18:17:45 -0000
> @@ -2621,13 +2621,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
>               }
>               ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
>               table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
> -             NET_LOCK();
> -             PF_LOCK();
>               /* first makes sure everything will succeed */
>               for (i = 0; i < io->size; i++) {
>                       if (copyin(io->array+i, ioe, sizeof(*ioe))) {
> -                             PF_UNLOCK();
> -                             NET_UNLOCK();
>                               free(table, M_TEMP, sizeof(*table));
>                               free(ioe, M_TEMP, sizeof(*ioe));
>                               error = EFAULT;
> @@ -2635,13 +2631,13 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
>                       }
>                       if (strnlen(ioe->anchor, sizeof(ioe->anchor)) ==
>                           sizeof(ioe->anchor)) {
> -                             PF_UNLOCK();
> -                             NET_UNLOCK();
>                               free(table, M_TEMP, sizeof(*table));
>                               free(ioe, M_TEMP, sizeof(*ioe));
>                               error = ENAMETOOLONG;
>                               goto fail;
>                       }
> +                     NET_LOCK();
> +                     PF_LOCK();
>                       switch (ioe->type) {
>                       case PF_TRANS_TABLE:
>                               rs = pf_find_ruleset(ioe->anchor);
> @@ -2677,7 +2673,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
>                               error = EINVAL;
>                               goto fail;
>                       }
> +                     PF_UNLOCK();
> +                     NET_UNLOCK();
>               }
> +             NET_LOCK();
> +             PF_LOCK();
>  
>               /*
>                * Checked already in DIOCSETLIMIT, but check again as the
> @@ -2696,9 +2696,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
>               }
>               /* now do the commit - no errors should happen here */
>               for (i = 0; i < io->size; i++) {
> +                     PF_UNLOCK();
> +                     NET_UNLOCK();
>                       if (copyin(io->array+i, ioe, sizeof(*ioe))) {
> -                             PF_UNLOCK();
> -                             NET_UNLOCK();
>                               free(table, M_TEMP, sizeof(*table));
>                               free(ioe, M_TEMP, sizeof(*ioe));
>                               error = EFAULT;
> @@ -2706,13 +2706,13 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
>                       }
>                       if (strnlen(ioe->anchor, sizeof(ioe->anchor)) ==
>                           sizeof(ioe->anchor)) {
> -                             PF_UNLOCK();
> -                             NET_UNLOCK();
>                               free(table, M_TEMP, sizeof(*table));
>                               free(ioe, M_TEMP, sizeof(*ioe));
>                               error = ENAMETOOLONG;
>                               goto fail;
>                       }
> +                     NET_LOCK();
> +                     PF_LOCK();
>                       switch (ioe->type) {
>                       case PF_TRANS_TABLE:
>                               memset(table, 0, sizeof(*table));

Reply via email to