Bug 274614 - Issues with retry loop in pfctl_do_ioctl()
Summary: Issues with retry loop in pfctl_do_ioctl()
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-pf (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-10-20 16:57 UTC by Nick Reilly
Modified: 2023-11-01 09:06 UTC (History)
2 users (show)

See Also:
linimon: maintainer-feedback? (pf)


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Nick Reilly 2023-10-20 16:57:55 UTC
The retry loop in pfctl_do_ioctl() is problematic.

"data" is allocated outside the loop vi nvlist_pack() and then freed inside on the first time through. If ENOSPC is returned from the ioctl() then it goes to the retry and will now attempt to memcpy() the previously freed data before freeing it again.

There was a recent fix just before the retry loop https://cgit.freebsd.org/src/commit/lib/libpfctl/libpfctl.c?id=6422599e74db4bb8b47cead46760d96601d8396a
without that there are even more problems where the memcpy() of nvlen could be greater than the malloc() of size. This fix means that simply moving the retry label up above the nvlist_pack() will not work as that would then undo the increasing of size on the retry.
Comment 1 commit-hook freebsd_committer freebsd_triage 2023-10-24 09:34:27 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=2cffb52514b070e716e700c7f58fdb8cd9b05335

commit 2cffb52514b070e716e700c7f58fdb8cd9b05335
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2023-10-23 11:43:52 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2023-10-24 07:50:31 +0000

    libpfctl: fix pfctl_do_ioctl()

    pfctl_do_ioctl() copies the packed request data into the request buffer
    and then frees it. However, it's possible for the buffer to be too small
    for the reply, causing us to allocate a new buffer. We then copied from
    the freed request, and freed it again.

    Do not free the request buffer until we're all the way done.

    PR:             274614
    Reviewed by:    emaste
    MFC after:      1 week
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D42329

 lib/libpfctl/libpfctl.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
Comment 2 commit-hook freebsd_committer freebsd_triage 2023-11-01 09:06:51 UTC
A commit in branch stable/14 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=9f5ab6bddfc0974b385f2a198878f739424fd040

commit 9f5ab6bddfc0974b385f2a198878f739424fd040
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2023-10-23 11:43:52 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2023-11-01 09:05:49 +0000

    libpfctl: fix pfctl_do_ioctl()

    pfctl_do_ioctl() copies the packed request data into the request buffer
    and then frees it. However, it's possible for the buffer to be too small
    for the reply, causing us to allocate a new buffer. We then copied from
    the freed request, and freed it again.

    Do not free the request buffer until we're all the way done.

    PR:             274614
    Reviewed by:    emaste
    MFC after:      1 week
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D42329

    (cherry picked from commit 2cffb52514b070e716e700c7f58fdb8cd9b05335)

 lib/libpfctl/libpfctl.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
Comment 3 commit-hook freebsd_committer freebsd_triage 2023-11-01 09:06:52 UTC
A commit in branch stable/13 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=a17aa2314d5078060417cbfba30b20088359ec21

commit a17aa2314d5078060417cbfba30b20088359ec21
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2023-10-23 11:43:52 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2023-10-31 08:08:46 +0000

    libpfctl: fix pfctl_do_ioctl()

    pfctl_do_ioctl() copies the packed request data into the request buffer
    and then frees it. However, it's possible for the buffer to be too small
    for the reply, causing us to allocate a new buffer. We then copied from
    the freed request, and freed it again.

    Do not free the request buffer until we're all the way done.

    PR:             274614
    Reviewed by:    emaste
    MFC after:      1 week
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D42329

    (cherry picked from commit 2cffb52514b070e716e700c7f58fdb8cd9b05335)

 lib/libpfctl/libpfctl.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)