Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 87d56b77 authored by Daniel Starke's avatar Daniel Starke Committed by Greg Kroah-Hartman
Browse files

tty: n_gsm: fix wrong command retry handling

commit d0bcdffcad5a22f202e3bf37190c0dd8c080ea92 upstream.

n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010.
See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516


The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to
the newer 27.010 here. Chapter 5.7.3 states that the valid range for the
maximum number of retransmissions (N2) is from 0 to 255 (both including).
gsm_config() fails to limit this range correctly. Furthermore,
gsm_control_retransmit() handles this number incorrectly by performing
N2 - 1 retransmission attempts. Setting N2 to zero results in more than 255
retransmission attempts.
Fix the range check in gsm_config() and the value handling in
gsm_control_send() and gsm_control_retransmit() to comply with 3GPP 27.010.

Fixes: e1eaea46 ("tty: n_gsm line discipline")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarDaniel Starke <daniel.starke@siemens.com>
Link: https://lore.kernel.org/r/20220414094225.4527-11-daniel.starke@siemens.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a6e2bca9
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1329,7 +1329,6 @@ static void gsm_control_retransmit(struct timer_list *t)
	spin_lock_irqsave(&gsm->control_lock, flags);
	ctrl = gsm->pending_cmd;
	if (ctrl) {
		gsm->cretries--;
		if (gsm->cretries == 0) {
			gsm->pending_cmd = NULL;
			ctrl->error = -ETIMEDOUT;
@@ -1338,6 +1337,7 @@ static void gsm_control_retransmit(struct timer_list *t)
			wake_up(&gsm->event);
			return;
		}
		gsm->cretries--;
		gsm_control_transmit(gsm, ctrl);
		mod_timer(&gsm->t2_timer, jiffies + gsm->t2 * HZ / 100);
	}
@@ -1378,7 +1378,7 @@ static struct gsm_control *gsm_control_send(struct gsm_mux *gsm,

	/* If DLCI0 is in ADM mode skip retries, it won't respond */
	if (gsm->dlci[0]->mode == DLCI_MODE_ADM)
		gsm->cretries = 1;
		gsm->cretries = 0;
	else
		gsm->cretries = gsm->n2;

@@ -2517,7 +2517,7 @@ static int gsmld_config(struct tty_struct *tty, struct gsm_mux *gsm,
	/* Check the MRU/MTU range looks sane */
	if (c->mru > MAX_MRU || c->mtu > MAX_MTU || c->mru < 8 || c->mtu < 8)
		return -EINVAL;
	if (c->n2 < 3)
	if (c->n2 > 255)
		return -EINVAL;
	if (c->encapsulation > 1)	/* Basic, advanced, no I */
		return -EINVAL;