Bug 266124 - SIOCSTAT1 on /dev/ipstate causes a kernel stack buffer overflow
Summary: SIOCSTAT1 on /dev/ipstate causes a kernel stack buffer overflow
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: Cy Schubert
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-08-31 08:43 UTC by Robert Morris
Modified: 2022-09-28 14:50 UTC (History)
2 users (show)

See Also:


Attachments
Remove SIOCSTAT1 from ip_stat (2.71 KB, patch)
2022-09-06 21:06 UTC, Cy Schubert
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Morris 2022-08-31 08:43:47 UTC
netpfil/ipfilter/netinet/ip_fil.h says:

#define SIOCSTAT1       _IOWR('r', 78, struct ipfobj)

sizeof(struct ipfobj) is 56, and sys_ioctl() allocates space for the
input and return data on its stack (in smalldata[128]).

netpfil/ipfilter/netinet/ip_state.c says:

        /*
         * Return a copy of the hash table bucket lengths
         */
        case SIOCSTAT1 :
                error = BCOPYOUT(softs->ipf_state_stats.iss_bucketlen, data,
                                 softs->ipf_state_size * sizeof(u_int));

But the amount copied here is much larger than 56 (it's 22948 bytes
when I try it).

A demo:

int main() {
  int fd = open("/dev/ipstate", 2);
  if(fd < 0) { perror("/dev/ipstate"); exit(1); }
  char buf[128];
  memset(buf, 0, sizeof(buf));
  ioctl(fd, 0xc038724e, buf); // SIOCSTAT1
}

# uname -a
FreeBSD  14.0-CURRENT FreeBSD 14.0-CURRENT #40 main-n250928-b8170f38ccc7-dirty: Mon Aug 29 13:09:55 EDT 2022     rtm@xxx:/usr/obj/usr/rtm/symbsd/src/riscv.riscv64/sys/RTM riscv
# cc x.c
# ./a.out
panic: vm_fault_lookup: fault on nofault entry, addr: 0xffffffc0035f5000
panic() at panic+0x2a
vm_fault_lookup() at vm_fault_lookup+0x1bc
vm_fault() at vm_fault+0x9c
vm_fault_trap() at vm_fault_trap+0x66
page_fault_handler() at page_fault_handler+0x17a
do_trap_supervisor() at do_trap_supervisor+0x76
cpu_exception_handler_supervisor() at cpu_exception_handler_supervisor+0x70
--- exception 15, tval = 0xffffffc0035f5000
memcpy() at memcpy+0xf8
ipf_state_ioctl() at ipf_state_ioctl+0x1be
ipf_ioctlswitch() at ipf_ioctlswitch+0xb2
ipfioctl() at ipfioctl+0x224
devfs_ioctl() at devfs_ioctl+0xbe
VOP_IOCTL_APV() at VOP_IOCTL_APV+0x30
VOP_IOCTL() at VOP_IOCTL+0x36
vn_ioctl() at vn_ioctl+0xba
devfs_ioctl_f() at devfs_ioctl_f+0x20
fo_ioctl() at fo_ioctl+0xa
kern_ioctl() at kern_ioctl+0x242
sys_ioctl() at sys_ioctl+0x120
Comment 1 Cy Schubert freebsd_committer freebsd_triage 2022-09-06 20:52:07 UTC
ipfilter doesn't use this ioctl here. It's only used to display authentication statistics. I suspect the IOCTL in ip_state was added to support some yet to be developed feature. I'm inclined to remove it from ip_state and keep it in ip_auth. Unless of course you can think of some reason to keep it.

Reviewing Darren's original sources, which I converted from CVS to GIT, there is also no mention of SIOCSTAT1 nor SIOCATHST except for authentication stats, which begs the question why is this in ip_state in the first place, except to support some future feature that never materialized.

Removing it entirely from ip_state and keeping it in ip_auth is the best course of action. Thoughts?
Comment 2 Cy Schubert freebsd_committer freebsd_triage 2022-09-06 21:06:50 UTC
Created attachment 236403 [details]
Remove SIOCSTAT1 from ip_stat

Only ipstat -A should use this ioctl. Let's remove it.

I've also included another patch in my ipf-work branch that removes an HP-UX only feature. HP-UX is almost no more and my plans are to port my work over to illumos (in addition to sending patches to the NetBSD folks) when I find the time.

Let me know if this is acceptable for now.
Comment 3 commit-hook freebsd_committer freebsd_triage 2022-09-07 03:12:46 UTC
A commit in branch main references this bug:

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

commit 1f7a710ab35845049f17958c3783041c214d8a3c
Author:     Cy Schubert <cy@FreeBSD.org>
AuthorDate: 2022-09-06 20:58:35 +0000
Commit:     Cy Schubert <cy@FreeBSD.org>
CommitDate: 2022-09-07 02:57:05 +0000

    ipfilter: Remove unused ioctl

    The SIOCSTAT1 ioctl is only used in ip_auth and is unused in ip_state.
    The ip_state version was likely added to support a new statistic yet
    to be developed in ipfstat(8) or for some sample userspace application
    (similar in fashion to the sample provided for authentication rules).
    There is no need to report individual state hash table bucket lengths
    to any future userspace application.

    If needed for any future debugging purposes a DTrace probe would be a
    better vehicle.

    This unused ioctl in ip_stat results in a panic.

    PR:             266124
    Reported by:    Robert Morris <rtm@lcs.mit.edu>
    MFC after:      3 days

 sys/netpfil/ipfilter/netinet/ip_state.c | 12 ------------
 1 file changed, 12 deletions(-)
Comment 4 commit-hook freebsd_committer freebsd_triage 2022-09-11 12:37:44 UTC
A commit in branch stable/13 references this bug:

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

commit b9d5f7669a02ace316823069b53f8578b2e45818
Author:     Cy Schubert <cy@FreeBSD.org>
AuthorDate: 2022-09-06 20:58:35 +0000
Commit:     Cy Schubert <cy@FreeBSD.org>
CommitDate: 2022-09-11 12:36:30 +0000

    ipfilter: Remove unused ioctl

    The SIOCSTAT1 ioctl is only used in ip_auth and is unused in ip_state.
    The ip_state version was likely added to support a new statistic yet
    to be developed in ipfstat(8) or for some sample userspace application
    (similar in fashion to the sample provided for authentication rules).
    There is no need to report individual state hash table bucket lengths
    to any future userspace application.

    If needed for any future debugging purposes a DTrace probe would be a
    better vehicle.

    This unused ioctl in ip_stat results in a panic.

    PR:             266124
    Reported by:    Robert Morris <rtm@lcs.mit.edu>

    (cherry picked from commit 1f7a710ab35845049f17958c3783041c214d8a3c)

 sys/netpfil/ipfilter/netinet/ip_state.c | 12 ------------
 1 file changed, 12 deletions(-)
Comment 5 commit-hook freebsd_committer freebsd_triage 2022-09-11 12:38:45 UTC
A commit in branch stable/12 references this bug:

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

commit 55543349168a193e0f2ab4375e90845af9a64d59
Author:     Cy Schubert <cy@FreeBSD.org>
AuthorDate: 2022-09-06 20:58:35 +0000
Commit:     Cy Schubert <cy@FreeBSD.org>
CommitDate: 2022-09-11 12:37:50 +0000

    ipfilter: Remove unused ioctl

    The SIOCSTAT1 ioctl is only used in ip_auth and is unused in ip_state.
    The ip_state version was likely added to support a new statistic yet
    to be developed in ipfstat(8) or for some sample userspace application
    (similar in fashion to the sample provided for authentication rules).
    There is no need to report individual state hash table bucket lengths
    to any future userspace application.

    If needed for any future debugging purposes a DTrace probe would be a
    better vehicle.

    This unused ioctl in ip_stat results in a panic.

    PR:             266124
    Reported by:    Robert Morris <rtm@lcs.mit.edu>

    (cherry picked from commit 1f7a710ab35845049f17958c3783041c214d8a3c)

 sys/netpfil/ipfilter/netinet/ip_state.c | 12 ------------
 1 file changed, 12 deletions(-)
Comment 6 Cy Schubert freebsd_committer freebsd_triage 2022-09-28 14:50:23 UTC
fixed.