From ff917923f4fb9c83717ba135ee47d7e4c1567bb7 Mon Sep 17 00:00:00 2001 From: Muhammad Bilal Date: Tue, 28 Jul 2026 17:54:55 +0500 Subject: staging: rtl8723bs: fix OOB read in rtw_action_frame_parse() rtw_action_frame_parse() takes a frame_len parameter but never actually checks it before indexing into the frame body: const u8 *frame_body = frame + sizeof(struct ieee80211_hdr_3addr); ... c = frame_body[0]; ... a = frame_body[1]; frame_body already points 24 bytes (sizeof(struct ieee80211_hdr_3addr)) into frame, so reading frame_body[0] and frame_body[1] requires frame_len >= 26. A management action frame shorter than that (e.g. exactly 24 bytes, the minimum a malicious peer can send) causes a 1-2 byte out-of-bounds read. This is reachable from rtw_cfg80211_monitor_if_xmit_entry() and cfg80211_rtw_mgmt_tx() in ioctl_cfg80211.c, both of which pass attacker/user-influenced frame buffers and lengths straight through. Add the missing length check before frame_body is dereferenced. Fixes: 554c0a3abf216 ("staging: Add rtl8723bs sdio wifi driver") Cc: stable@vger.kernel.org Signed-off-by: Muhammad Bilal Link: https://patch.msgid.link/20260728125456.32359-3-meatuni001@gmail.com Signed-off-by: Greg Kroah-Hartman --- scripts/objdiff | 162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100755 scripts/objdiff (limited to 'scripts/objdiff') diff --git a/scripts/objdiff b/scripts/objdiff new file mode 100755 index 000000000..0685bc3ce --- /dev/null +++ b/scripts/objdiff @@ -0,0 +1,162 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-only + +# objdiff - a small script for validating that a commit or series of commits +# didn't change object code. +# +# Copyright 2014, Jason Cooper +# + +# usage example: +# +# $ git checkout COMMIT_A +# $ +# $ ./scripts/objdiff record path/to/*.o +# +# $ git checkout COMMIT_B +# $ +# $ ./scripts/objdiff record path/to/*.o +# +# $ ./scripts/objdiff diff COMMIT_A COMMIT_B +# $ + +# And to clean up (everything is in .objdiff/*) +# $ ./scripts/objdiff clean all +# +# Note: 'make mrproper' will also remove .objdiff + +SRCTREE=$(cd $(git rev-parse --show-toplevel 2>/dev/null); pwd) + +if [ -z "$SRCTREE" ]; then + echo >&2 "ERROR: Not a git repository." + exit 1 +fi + +TMPD=$SRCTREE/.objdiff + +usage() { + echo >&2 "Usage: $0 " + echo >&2 " record " + echo >&2 " diff " + echo >&2 " clean all | " + exit 1 +} + +get_output_dir() { + dir=${1%/*} + + if [ "$dir" = "$1" ]; then + dir=. + fi + + dir=$(cd $dir; pwd) + + echo $TMPD/$CMT${dir#$SRCTREE} +} + +do_objdump() { + dir=$(get_output_dir $1) + base=${1##*/} + stripped=$dir/${base%.o}.stripped + dis=$dir/${base%.o}.dis + + [ ! -d "$dir" ] && mkdir -p $dir + + # remove addresses for a cleaner diff + # http://dummdida.tumblr.com/post/60924060451/binary-diff-between-libc-from-scientificlinux-and + $STRIP -g $1 -R __bug_table -R .note -R .comment -o $stripped + $OBJDUMP -D $stripped | sed -e "s/^[[:space:]]\+[0-9a-f]\+//" -e "s:^$stripped:$1:" > $dis +} + +dorecord() { + [ $# -eq 0 ] && usage + + FILES="$*" + + CMT="`git rev-parse --short HEAD`" + + STRIP="${CROSS_COMPILE}strip" + OBJDUMP="${CROSS_COMPILE}objdump" + + for d in $FILES; do + if [ -d "$d" ]; then + for f in $(find $d -name '*.o') + do + do_objdump $f + done + else + do_objdump $d + fi + done +} + +dodiff() { + [ $# -ne 2 ] && [ $# -ne 0 ] && usage + + if [ $# -eq 0 ]; then + SRC="`git rev-parse --short HEAD^`" + DST="`git rev-parse --short HEAD`" + else + SRC="`git rev-parse --short $1`" + DST="`git rev-parse --short $2`" + fi + + DIFF="`which colordiff`" + + if [ ${#DIFF} -eq 0 ] || [ ! -x "$DIFF" ]; then + DIFF="`which diff`" + fi + + SRCD="$TMPD/$SRC" + DSTD="$TMPD/$DST" + + if [ ! -d "$SRCD" ]; then + echo >&2 "ERROR: $SRCD doesn't exist" + exit 1 + fi + + if [ ! -d "$DSTD" ]; then + echo >&2 "ERROR: $DSTD doesn't exist" + exit 1 + fi + + $DIFF -Nurd $SRCD $DSTD +} + +doclean() { + [ $# -eq 0 ] && usage + [ $# -gt 1 ] && usage + + if [ "x$1" = "xall" ]; then + rm -rf $TMPD/* + else + CMT="`git rev-parse --short $1`" + + if [ -d "$TMPD/$CMT" ]; then + rm -rf $TMPD/$CMT + else + echo >&2 "$CMT not found" + fi + fi +} + +[ $# -eq 0 ] && usage + +case "$1" in + record) + shift + dorecord $* + ;; + diff) + shift + dodiff $* + ;; + clean) + shift + doclean $* + ;; + *) + echo >&2 "Unrecognized command '$1'" + exit 1 + ;; +esac -- cgit v1.3.1