Bug 269347 - 802.11 mesh peer can overrun b[] in mesh_decap()
Summary: 802.11 mesh peer can overrun b[] in mesh_decap()
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: wireless (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-wireless (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-02-05 19:59 UTC by Robert Morris
Modified: 2023-08-02 23:25 UTC (History)
2 users (show)

See Also:


Attachments
generate an 802.11 mesh packet that causes an overrun of b[] in mesh_decap() (1.90 KB, text/plain)
2023-02-05 19:59 UTC, Robert Morris
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Morris 2023-02-05 19:59:18 UTC
Created attachment 239928 [details]
generate an 802.11 mesh packet that causes an overrun of b[] in mesh_decap()

mesh_decap(..., int hdrlen, ...) says:

        uint8_t b[sizeof(struct ieee80211_qosframe_addr4) +
                  sizeof(struct ieee80211_meshcntl_ae10)];
        ...;
        memcpy(b, mtod(m, caddr_t), hdrlen);

sizeof(b) is 50.

However, the hdrlen that mesh_input() passes to mesh_decap() can be as
large as 56, so memcpy() overruns b[]. This happens if the packet's
"ae" here in mesh_input() is 3:

                mc = (const struct ieee80211_meshcntl *)
                    (mtod(m, const uint8_t *) + hdrspace);
                ae = mc->mc_flags & IEEE80211_MESH_AE_MASK;
                meshdrlen = sizeof(struct ieee80211_meshcntl) +
                    ae * IEEE80211_ADDR_LEN;
                hdrspace += meshdrlen;

I've attached a demo:

# cc wtap18a.c
# ./a.out
...
panic: stack overflow detected; backtrace may be corrupted
panic() at panic+0x2a
__stack_chk_fail() at __stack_chk_fail+0x14
mesh_decap() at mesh_decap+0x354
mesh_input() at mesh_input+0x770
.LBB2_17() at .LBB2_17+0x34
taskqueue_run_locked() at taskqueue_run_locked+0x96
taskqueue_thread_loop() at taskqueue_thread_loop+0x62
fork_exit() at fork_exit+0x80
fork_trampoline() at fork_trampoline+0xa