Bug 284904 - buffer overflow in if_umb.c umb_in_len2mask()
Summary: buffer overflow in if_umb.c umb_in_len2mask()
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: usb (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: Pierre Pronchery
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-02-19 18:37 UTC by Robert Morris
Modified: 2025-05-29 14:00 UTC (History)
2 users (show)

See Also:


Attachments
0001-umb-avoid-buffer-overflow-in-umb_in_len2mask.patch (1.28 KB, patch)
2025-05-26 23:37 UTC, Pierre Pronchery
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Morris 2025-02-19 18:37:28 UTC
umb_in_len2mask(mask, len) will write as many as len/8 bytes:

        for (i = 0; i < len / 8; i++)
                p[i] = 0xff;

len comes from a ipv4elem.prefixlen in a MBIM_CID_IP_CONFIGURATION
message from the USB device, and can be any uint32_t value. So a broken
or malicious USB device can cause a buffer overflow.

Here's a backtrace from just before a crash:

#0  umb_in_len2mask (mask=0xffffffc0826c69c0, len=50331648)
    at /usr/rtm/symbsd/src/sys/dev/usb/net/if_umb.c:1448
#1  umb_add_inet_config (sc=0xffffffc094c4d000, ip=..., prefixlen=50331648, 
    gw=...) at /usr/rtm/symbsd/src/sys/dev/usb/net/if_umb.c:1778
#2  0xffffffc00026fe1e in umb_decode_ip_configuration (sc=0xffffffc094c4d000, 
    data=0xffffffd00cbb9330, len=<optimized out>)
    at /usr/rtm/symbsd/src/sys/dev/usb/net/if_umb.c:1855
#3  umb_decode_cid (sc=0xffffffc094c4d000, cid=<optimized out>, 
    data=0xffffffd00cbb9330, len=<optimized out>)
    at /usr/rtm/symbsd/src/sys/dev/usb/net/if_umb.c:2685
#4  0xffffffc00026db7e in umb_decode_response (sc=0xffffffc094c4d000, 
    response=0xffffffd00cbb9300, len=128)
    at /usr/rtm/symbsd/src/sys/dev/usb/net/if_umb.c:1355
#5  umb_get_response_task (msg=<optimized out>)
    at /usr/rtm/symbsd/src/sys/dev/usb/net/if_umb.c:1243
#6  0xffffffc0002552da in usb_process (arg=0xffffffc094c4d078)
    at /usr/rtm/symbsd/src/sys/dev/usb/usb_process.c:160
#7  0xffffffc0003f8750 in fork_exit (callout=0xffffffc0002551de <usb_process>, 
    arg=0xffffffc094c4d078, frame=0xffffffc0826c6c40)
    at /usr/rtm/symbsd/src/sys/kern/kern_fork.c:1152
#8  0xffffffc0007efbee in fork_trampoline ()
    at /usr/rtm/symbsd/src/sys/riscv/riscv/swtch.S:370
Comment 1 Pierre Pronchery freebsd_committer freebsd_triage 2025-05-24 22:59:25 UTC
I think you are right, although ISTM that the length value might even be set by the network. Either way it is bad enough, and I believe the bug is also found upstream at OpenBSD; I have let them know about the issue.
Comment 2 Pierre Pronchery freebsd_committer freebsd_triage 2025-05-26 23:37:37 UTC
Created attachment 260725 [details]
0001-umb-avoid-buffer-overflow-in-umb_in_len2mask.patch

This fix is from Gerhard Roth, and was obtained after coordination upstream with OpenBSD.

Can you confirm that it fixes the issue for you?
Comment 3 Robert Morris 2025-05-27 11:47:59 UTC
(In reply to Pierre Pronchery from comment #2)
Yes: the patch fixes the problem for me.
Comment 4 commit-hook freebsd_committer freebsd_triage 2025-05-29 13:10:27 UTC
A commit in branch main references this bug:

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

commit 5ed36e2e1729d6a49a65366c03fc15515967ae67
Author:     Pierre Pronchery <khorben@FreeBSD.org>
AuthorDate: 2025-05-26 23:18:53 +0000
Commit:     Pierre Pronchery <khorben@FreeBSD.org>
CommitDate: 2025-05-29 13:07:52 +0000

    umb: avoid buffer overflow in umb_in_len2mask()

    len comes from ipv4elem.prefixlen in a MBIM_CID_IP_CONFIGURATION message
    from the USB device, and should not be trusted, as it could be any
    uint32_t value. Without this extra check, a potential buffer overflow
    could subsequently occur in umb_in_len2mask().

    Fix from Gerhard Roth, after coordination upstream with OpenBSD.

    PR:             284904
    Reported by:    Robert Morris <rtm@lcs.mit.edu>
    Approved by:    philip (mentor)
    Sponsored by:   The FreeBSD Foundation

 sys/dev/usb/net/if_umb.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)