Bug 290992

Summary: Inconsistent input validation in quot's -n mode
Product: Base System Reporter: Igor Gabriel S. Souza <igor>
Component: binAssignee: Dag-Erling Smørgrav <des>
Status: Closed FIXED    
Severity: Affects Many People CC: des, ziaee
Priority: --- Flags: des: mfc-stable15+
des: mfc-stable14+
des: mfc-stable13+
Version: 14.3-RELEASE   
Hardware: amd64   
OS: Any   
URL: https://reviews.freebsd.org/D53726

Description Igor Gabriel S. Souza 2025-11-13 04:19:06 UTC
Title: Denial of Service in `quot` via Improper Input Validation in `donames()` (`-n` mode)

Affected Software:
- Utility: quot (disk usage reporting tool in BSD systems)
- File: usr.sbin/quot/quot.c
- Function: donames()
- Likely affected: FreeBSD, NetBSD, OpenBSD, and other BSD derivatives shipping quot

Vulnerability Type:
- CWE-20: Improper Input Validation
- CWE-704: Incorrect Type Conversion or Cast

Summary:
The quot utility, when executed with the -n flag to process a list of inodes from standard input, fails to properly handle negative values. The function donames() reads input using `scanf("%ju", &inode)`, which implicitly converts negative values like `-1` into large unsigned values (e.g., 18446744073709551615).

If this value exceeds the max inode limit (`maxino`), the code triggers a return statement, aborting all further processing. As a result, valid entries following the malformed input are never processed.

Impact:
- Denial of Service (DoS) by halting inode analysis early
- Suppression of valid user accounting
- Potential to skew disk usage reporting

CVSS v3.1 Vector:
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:H
Base Score: 6.1 (Medium)

Steps to Reproduce (PoC):

1. Create UFS image:

dd if=/dev/zero of=ufs.img bs=1M count=50
mdconfig -a -t vnode -f ufs.img -u 0
newfs -U /dev/md0
mount /dev/md0 /mnt
touch /mnt/file1 /mnt/file2
umount /mnt

2. Trigger the bug:

printf "1\n2\n-1\n3\n4\n" | quot -n /dev/md0

Expected Output:

/dev/md0:
root
quot: illegal inode 18446744073709551615

Result: Entries "3" and "4" are not processed due to premature return.

Root Cause:

scanf("%ju", &inode); // Negative numbers parsed as large unsigned ints

if (inode > maxino) {
    warnx("illegal inode %ju", inode);
    return;  // Halts processing, breaking expected flow
}

Credits:
Author: Igor Gabriel Sousa e Souza
Email: igor@bsdtrust.com
LinkedIn: https://www.linkedin.com/in/igo0r
Comment 1 Dag-Erling Smørgrav freebsd_committer freebsd_triage 2025-11-13 10:28:09 UTC
1. Negative inode numbers aren't valid either, so I don't see what difference this makes.
2. Aborting on invalid input is an implementation choice, not a bug.
3. As you've already been told, quot is not a security boundary.
4. When reporting a bug, “expected output” usually means the output one would expect if the program worked correctly.

That being said, donames() is wildly inconsistent in how it handles different types of invalid input, so it's worth rewriting.
Comment 2 commit-hook freebsd_committer freebsd_triage 2025-11-14 14:30:05 UTC
A commit in branch main references this bug:

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

commit fa272a5276865a97b01823fe6546940eaaf1b164
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-11-14 14:28:40 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-11-14 14:29:05 +0000

    quot: Rewrite -n mode input parser

    The existing parser was needlessly complicated and wildly inconsistent
    in how it handled invalid input.  Rewrite using getline() and treat
    invalid input consistently: silently ignore lines that don't begin with
    a number, and print a warning if the inode number is out of range.

    PR:             290992
    MFC after:      1 week
    Reviewed by:    obrien
    Differential Revision:  https://reviews.freebsd.org/D53726

 usr.sbin/quot/quot.8             |  3 ++-
 usr.sbin/quot/quot.c             | 47 +++++++++++++++++++++-------------------
 usr.sbin/quot/tests/quot_test.sh | 19 ++++++++++++++++
 3 files changed, 46 insertions(+), 23 deletions(-)
Comment 3 commit-hook freebsd_committer freebsd_triage 2025-11-19 10:58:52 UTC
A commit in branch stable/15 references this bug:

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

commit d019d36707d35a982d527f568dd68179f6f747b2
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-11-14 14:28:40 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-11-19 10:56:50 +0000

    quot: Rewrite -n mode input parser

    The existing parser was needlessly complicated and wildly inconsistent
    in how it handled invalid input.  Rewrite using getline() and treat
    invalid input consistently: silently ignore lines that don't begin with
    a number, and print a warning if the inode number is out of range.

    PR:             290992
    MFC after:      1 week
    Reviewed by:    obrien
    Differential Revision:  https://reviews.freebsd.org/D53726

    (cherry picked from commit fa272a5276865a97b01823fe6546940eaaf1b164)

 usr.sbin/quot/quot.8             |  3 ++-
 usr.sbin/quot/quot.c             | 47 +++++++++++++++++++++-------------------
 usr.sbin/quot/tests/quot_test.sh | 19 ++++++++++++++++
 3 files changed, 46 insertions(+), 23 deletions(-)
Comment 4 commit-hook freebsd_committer freebsd_triage 2025-11-19 11:19:57 UTC
A commit in branch stable/14 references this bug:

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

commit 179fa1d81c73ab7ef231e17da73f230e4f8ee5a2
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-11-14 14:28:40 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-11-19 11:19:07 +0000

    quot: Rewrite -n mode input parser

    The existing parser was needlessly complicated and wildly inconsistent
    in how it handled invalid input.  Rewrite using getline() and treat
    invalid input consistently: silently ignore lines that don't begin with
    a number, and print a warning if the inode number is out of range.

    PR:             290992
    MFC after:      1 week
    Reviewed by:    obrien
    Differential Revision:  https://reviews.freebsd.org/D53726

    (cherry picked from commit fa272a5276865a97b01823fe6546940eaaf1b164)

 usr.sbin/quot/quot.8             |  3 ++-
 usr.sbin/quot/quot.c             | 47 ++++++++++++++++++++++------------------
 usr.sbin/quot/tests/quot_test.sh | 19 ++++++++++++++++
 3 files changed, 47 insertions(+), 22 deletions(-)
Comment 5 commit-hook freebsd_committer freebsd_triage 2025-11-19 11:21:59 UTC
A commit in branch stable/13 references this bug:

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

commit a2630fec78b60844e68cae8b9e1f65b7322a5f05
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-11-14 14:28:40 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-11-19 11:20:30 +0000

    quot: Rewrite -n mode input parser

    The existing parser was needlessly complicated and wildly inconsistent
    in how it handled invalid input.  Rewrite using getline() and treat
    invalid input consistently: silently ignore lines that don't begin with
    a number, and print a warning if the inode number is out of range.

    PR:             290992
    MFC after:      1 week
    Reviewed by:    obrien
    Differential Revision:  https://reviews.freebsd.org/D53726

    (cherry picked from commit fa272a5276865a97b01823fe6546940eaaf1b164)
    (cherry picked from commit 179fa1d81c73ab7ef231e17da73f230e4f8ee5a2)

 usr.sbin/quot/quot.8             |  3 ++-
 usr.sbin/quot/quot.c             | 47 ++++++++++++++++++++++------------------
 usr.sbin/quot/tests/quot_test.sh | 19 ++++++++++++++++
 3 files changed, 47 insertions(+), 22 deletions(-)