Bug 269347

Summary: 802.11 mesh peer can overrun b[] in mesh_decap()
Product: Base System Reporter: Robert Morris <rtm>
Component: wirelessAssignee: freebsd-wireless (Nobody) <wireless>
Status: Open ---    
Severity: Affects Some People CC: bz, emaste
Priority: ---    
Version: CURRENT   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
generate an 802.11 mesh packet that causes an overrun of b[] in mesh_decap() none

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