FAILED: patch "[PATCH] tty: n_gsm: fix possible out-of-bounds in gsm0_receive()" failed to apply to 4.19-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.19-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-4.19.y
git checkout FETCH_HEAD
git cherry-pick -x 47388e807f85948eefc403a8a5fdc5b406a65d5a
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024052539-pacific-rejoin-8bca@gregkh' --subject-prefix 'PATCH 4.19.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 47388e807f85948eefc403a8a5fdc5b406a65d5a Mon Sep 17 00:00:00 2001
From: Daniel Starke <[email protected]>
Date: Wed, 24 Apr 2024 07:48:41 +0200
Subject: [PATCH] tty: n_gsm: fix possible out-of-bounds in gsm0_receive()
Assuming the following:
- side A configures the n_gsm in basic option mode
- side B sends the header of a basic option mode frame with data length 1
- side A switches to advanced option mode
- side B sends 2 data bytes which exceeds gsm->len
Reason: gsm->len is not used in advanced option mode.
- side A switches to basic option mode
- side B keeps sending until gsm0_receive() writes past gsm->buf
Reason: Neither gsm->state nor gsm->len have been reset after reconfiguration.
Fix this by changing gsm->count to gsm->len comparison from equal to less than. Also add upper limit checks against the constant MAX_MRU in gsm0_receive() and gsm1_receive() to harden against memory corruption of gsm->len and gsm->mru.
All other checks remain as we still need to limit the data according to the user configuration and actual payload size.
drivers/tty/n_gsm.c +5 -2
@@ -2913,7 +2913,10 @@ static void gsm0_receive(struct gsm_mux *gsm, u8 c)break ;case GSM_DATA :/* Data */ gsm->buf[gsm->count++] = c; -if (gsm->count == gsm->len) { +if (gsm->count >=MAX_MRU ) { + gsm->bad_size++; + gsm->state =GSM_SEARCH ; + }else if (gsm->count >= gsm->len) {/* Calculate final FCS for UI frames over all data */ if ((gsm->control & ~PF ) !=UIH ) { gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf,
@@ -3026,7 +3029,7 @@ static void gsm1_receive(struct gsm_mux *gsm, u8 c) gsm->state =GSM_DATA ;break ;case GSM_DATA :/* Data */ -if (gsm->count > gsm->mru) {/* Allow one for the FCS */ +if (gsm->count > gsm->mru || gsm->count >MAX_MRU ) {/* Allow one for the FCS */ gsm->state =GSM_OVERRUN ; gsm->bad_size++; }else