Skip to content

[PW_SID:1097567] [v4] Bluetooth: RFCOMM: add minimum length check in rfcomm_recv_frame#218

Open
BluezTestBot wants to merge 1 commit into
workflowfrom
1097567
Open

[PW_SID:1097567] [v4] Bluetooth: RFCOMM: add minimum length check in rfcomm_recv_frame#218
BluezTestBot wants to merge 1 commit into
workflowfrom
1097567

Conversation

@BluezTestBot
Copy link
Copy Markdown

rfcomm_recv_frame() casts skb->data to struct rfcomm_hdr * and
immediately dereferences hdr->addr and hdr->ctrl without first
validating that skb->len is large enough to hold the header. A
remote device can send a crafted short RFCOMM frame over L2CAP to
trigger an out-of-bounds read before any session state is checked.

The FCS trimming code that follows compounds the problem:

    skb->len--; skb->tail--;

If skb->len is already zero the decrement wraps to UINT_MAX, causing
skb_tail_pointer() to return a pointer far outside the skb and
producing a second out-of-bounds read when the FCS byte is consumed.

Replace the open-coded cast with skb_pull_data() which validates
skb->len against sizeof(*hdr) and advances skb->data atomically.
Save the original skb->data as frame_start before the pull so that
__check_fcs() receives the header bytes as required by the RFCOMM
FCS specification. Guard against a missing FCS byte with an explicit
skb->len < 1 check. Replace the unsafe skb->tail decrement and
skb_tail_pointer() call with a direct end-of-data index and skb_trim().

Note: SeungJu Cheon posted a related patch that adds equivalent
length checks inside the individual MCC sub-handlers
(rfcomm_recv_pn, rfcomm_recv_rpn, rfcomm_recv_rls, rfcomm_recv_msc,
rfcomm_recv_mcc). That fix and this one are complementary and
independent; neither subsumes the other.

Fixes: 1da177e ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal meatuni001@gmail.com


v4:

  • Keep no-session comment and add blank line after header/len guard
    v3:
  • Replace open-coded cast with skb_pull_data() per Luiz's review
  • Save frame_start before skb_pull_data(); pass it to __check_fcs()
    to preserve correct FCS validation over the header bytes
  • Replace skb->tail decrement with skb_trim() per Luiz's review
    v2:
  • Fix GitLint B3: replace tab with spaces in commit body
  • Add Cc: stable@vger.kernel.org

net/bluetooth/rfcomm/core.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)

rfcomm_recv_frame() casts skb->data to struct rfcomm_hdr * and
immediately dereferences hdr->addr and hdr->ctrl without first
validating that skb->len is large enough to hold the header. A
remote device can send a crafted short RFCOMM frame over L2CAP to
trigger an out-of-bounds read before any session state is checked.

The FCS trimming code that follows compounds the problem:

        skb->len--; skb->tail--;

If skb->len is already zero the decrement wraps to UINT_MAX, causing
skb_tail_pointer() to return a pointer far outside the skb and
producing a second out-of-bounds read when the FCS byte is consumed.

Replace the open-coded cast with skb_pull_data() which validates
skb->len against sizeof(*hdr) and advances skb->data atomically.
Save the original skb->data as frame_start before the pull so that
__check_fcs() receives the header bytes as required by the RFCOMM
FCS specification. Guard against a missing FCS byte with an explicit
skb->len < 1 check. Replace the unsafe skb->tail decrement and
skb_tail_pointer() call with a direct end-of-data index and skb_trim().

Note: SeungJu Cheon posted a related patch that adds equivalent
length checks inside the individual MCC sub-handlers
(rfcomm_recv_pn, rfcomm_recv_rpn, rfcomm_recv_rls, rfcomm_recv_msc,
rfcomm_recv_mcc). That fix and this one are complementary and
independent; neither subsumes the other.

Fixes: 1da177e ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
@github-actions
Copy link
Copy Markdown

CheckPatch
Desc: Run checkpatch.pl script
Duration: 0.73 seconds
Result: PASS

@github-actions
Copy link
Copy Markdown

GitLint
Desc: Run gitlint
Duration: 0.55 seconds
Result: PASS

@github-actions
Copy link
Copy Markdown

SubjectPrefix
Desc: Check subject contains "Bluetooth" prefix
Duration: 0.12 seconds
Result: PASS

@github-actions
Copy link
Copy Markdown

BuildKernel
Desc: Build Kernel for Bluetooth
Duration: 25.91 seconds
Result: PASS

@github-actions
Copy link
Copy Markdown

CheckAllWarning
Desc: Run linux kernel with all warning enabled
Duration: 29.40 seconds
Result: PASS

@github-actions
Copy link
Copy Markdown

CheckSparse
Desc: Run sparse tool with linux kernel
Duration: 26.90 seconds
Result: PASS

@github-actions
Copy link
Copy Markdown

BuildKernel32
Desc: Build 32bit Kernel for Bluetooth
Duration: 24.98 seconds
Result: PASS

@github-actions
Copy link
Copy Markdown

TestRunnerSetup
Desc: Setup kernel and bluez for test-runner
Duration: 526.66 seconds
Result: PASS

@github-actions
Copy link
Copy Markdown

TestRunner_rfcomm-tester
Desc: Run rfcomm-tester with test-runner
Duration: 63.53 seconds
Result: PASS

@github-actions
Copy link
Copy Markdown

IncrementalBuild
Desc: Incremental build with the patches in the series
Duration: 24.66 seconds
Result: PASS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant