mainline inclusion from mainline-v6.5-rc7 commit 3c4f8333b582487a2d1e02171f1465531cde53e3 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I8QFUO CVE: CVE-2023-6546
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
In commit 9b9c8195f3f0 ("tty: n_gsm: fix UAF in gsm_cleanup_mux"), the UAF problem is not completely fixed. There is a race condition in gsm_cleanup_mux(), which caused this UAF.
The UAF problem is triggered by the following race: task[5046] task[5054] ----------------------- ----------------------- gsm_cleanup_mux(); dlci = gsm->dlci[0]; mutex_lock(&gsm->mutex); gsm_cleanup_mux(); dlci = gsm->dlci[0]; //Didn't take the lock gsm_dlci_release(gsm->dlci[i]); gsm->dlci[i] = NULL; mutex_unlock(&gsm->mutex); mutex_lock(&gsm->mutex); dlci->dead = true; //UAF
Fix it by assigning values after mutex_lock().
Link: https://syzkaller.appspot.com/text?tag=CrashReport&x=176188b5a80000 Cc: stable stable@kernel.org Fixes: 9b9c8195f3f0 ("tty: n_gsm: fix UAF in gsm_cleanup_mux") Fixes: aa371e96f05d ("tty: n_gsm: fix restart handling via CLD command") Signed-off-by: Yi Yang yiyang13@huawei.com Co-developed-by: Qiumiao Zhang zhangqiumiao1@huawei.com Signed-off-by: Qiumiao Zhang zhangqiumiao1@huawei.com Link: https://lore.kernel.org/r/20230811031121.153237-1-yiyang13@huawei.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
conflicts: drivers/tty/n_gsm.c
Signed-off-by: Yi Yang yiyang13@huawei.com --- drivers/tty/n_gsm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 3f08ad7e629a..c1851fd9149c 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2063,7 +2063,7 @@ static int gsm_disconnect(struct gsm_mux *gsm) static void gsm_cleanup_mux(struct gsm_mux *gsm) { int i; - struct gsm_dlci *dlci = gsm->dlci[0]; + struct gsm_dlci *dlci; struct gsm_msg *txq, *ntxq;
gsm->dead = 1; @@ -2082,11 +2082,12 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm)
del_timer_sync(&gsm->t2_timer); /* Now we are sure T2 has stopped */ + mutex_lock(&gsm->mutex); + dlci = gsm->dlci[0]; if (dlci) dlci->dead = 1;
/* Free up any link layer users */ - mutex_lock(&gsm->mutex); for (i = 0; i < NUM_DLCI; i++) if (gsm->dlci[i]) gsm_dlci_release(gsm->dlci[i]);