Bug 290992 - Inconsistent input validation in quot's -n mode
Summary: Inconsistent input validation in quot's -n mode
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: 14.3-RELEASE
Hardware: amd64 Any
: --- Affects Many People
Assignee: Dag-Erling Smørgrav
URL: https://reviews.freebsd.org/D53726
Keywords:
Depends on:
Blocks:
 
Reported: 2025-11-13 04:19 UTC by Igor Gabriel S. Souza
Modified: 2025-11-19 11:22 UTC (History)
2 users (show)

See Also:
des: mfc-stable15+
des: mfc-stable14+
des: mfc-stable13+


Attachments

Note You need to log in before you can comment on or make changes to this bug.
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(-)