From nobody Sun Feb 8 20:53:27 2026 Received: from dggsgout11.his.huawei.com (dggsgout11.his.huawei.com [45.249.212.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DE99918AE2 for ; Thu, 8 Jan 2026 02:50:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767840646; cv=none; b=Mj5LCB3ZKI/nMVYbyLAaRebBbfEkHaRaGtZPCtyJoLDR1v9azvFvXkGUmSe29L8rqgDBOMLgw8bDtDli/oimZB57UQkYYP9SM7N0iivHkkMdKk1hhCyyMEX46uu6xeQ+EJaJHK9MsK/8Fcgc4PokuIZLjcEt/9v8y+dgCuW7L/M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767840646; c=relaxed/simple; bh=fZiZ/Khv3rmmtXbvFI9ukQJguYaHEvoJVaJ+KUfl1wo=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=kcldqN3YGjqTwYBAhivoZfkC5vL6rxq+TYOo1fWQNV/WuB5ft9FbAQ6R9OFyIjUDbSS17xvhXJIp/nVH07V6Cn342tYtiavmkXdSWGgES/+pwrTcZBtrvrS7sHXyenfiPb6URFDS63bwEwFHAu3YmtjxTDWppXv/7qIu6nADzHY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com; spf=pass smtp.mailfrom=huaweicloud.com; arc=none smtp.client-ip=45.249.212.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=huaweicloud.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huaweicloud.com Received: from mail.maildlp.com (unknown [172.19.163.198]) by dggsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4dmqCK3WLWzYQtlw for ; Thu, 8 Jan 2026 10:50:37 +0800 (CST) Received: from mail02.huawei.com (unknown [10.116.40.128]) by mail.maildlp.com (Postfix) with ESMTP id 3453F4056B for ; Thu, 8 Jan 2026 10:50:40 +0800 (CST) Received: from huaweicloud.com (unknown [10.50.87.129]) by APP4 (Coremail) with SMTP id gCh0CgBHp_d_G19pt8kXDA--.46011S4; Thu, 08 Jan 2026 10:50:40 +0800 (CST) From: linan666@huaweicloud.com To: arnd@arndb.de, gregkh@linuxfoundation.org Cc: linux-kernel@vger.kernel.org, viro@zeniv.linux.org.uk, linan666@huaweicloud.com, wanghai38@huawei.com Subject: [PATCH v2] char: lp: Fix NULL pointer dereference of cad Date: Thu, 8 Jan 2026 10:41:55 +0800 Message-Id: <20260108024155.3800149-1-linan666@huaweicloud.com> X-Mailer: git-send-email 2.39.2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: gCh0CgBHp_d_G19pt8kXDA--.46011S4 X-Coremail-Antispam: 1UD129KBjvJXoWxAry5CryfCFW7GrykCw4fAFb_yoWrWF4xpa yFg3s8KrWrXFnrXFW7JF4q9FW5tr4IgFs7Ja1kJ3WIyw1kKr4jvFsrKF9YkFZ5CryxJFW3 XF40qa4j9ayUtF7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUU9C14x267AKxVW8JVW5JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26F1j6w1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4U JVWxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_Gc CE3s1lnxkEFVAIw20F6cxK64vIFxWle2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xv F2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI8IcVAFwI0_Jrv_JF1lYx0Ex4A2jsIE14v26r4UJV WxJr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8v x2IErcIFxwAKzVCY07xG64k0F24lc7CjxVAaw2AFwI0_JF0_Jw1l42xK82IYc2Ij64vIr4 1l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK 67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI 8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r1j6r4UMIIF0xvE42xK8VAv wI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14 v26r1j6r4UYxBIdaVFxhVjvjDU0xZFpf9x0JUBHqcUUUUU= X-CM-SenderInfo: polqt0awwwqx5xdzvxpfor3voofrz/ Content-Type: text/plain; charset="utf-8" From: Li Nan NULL pointer dereference occurs when accessing 'port->physport->cad' as below: KASAN: null-ptr-deref in range [0x00000000000003f0-0x00000000000003f7] RIP: 0010:parport_wait_peripheral+0x130/0x4b0 Call Trace: parport_ieee1284_write_compat+0x306/0xb70 ? __pfx_parport_ieee1284_write_compat+0x10/0x10 parport_write+0x1d6/0x660 lp_write+0x43e/0xbc0 ? __pfx_lp_write+0x10/0x10 vfs_write+0x21c/0x960 ksys_write+0x12e/0x260 ? __pfx_ksys_write+0x10/0x10 ? __audit_syscall_entry+0x39e/0x510 do_syscall_64+0x59/0x110 entry_SYSCALL_64_after_hwframe+0x78/0xe2 The root cause is other processes may set 'port->cad' to NULL during lp_write() operations. Process flow: T1 T2 lp_write lock port_mutex * lp_claim_parport_or_block parport_claim port->cad =3D dev; parport_write parport_ieee1284_write_compat lp_do_ioctl lp_reset lp_release_parport parport_release port->cad =3D NULL; parport_wait_peripheral port->physport->cad->timeout | NULL Fix this issue by adding 'port_mutex' protection. Like read/write and ioctl LPGETSTATUS, use this lock to protect port access and modification to prevent concurrency problems. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Li Nan --- v2: Use mutex_lock instead of mutex_lock_interruptible in lp_release(). drivers/char/lp.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 24417a00dfe9..82f2405b4502 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -520,9 +520,14 @@ static int lp_open(struct inode *inode, struct file *f= ile) should most likely only ever be used by the tunelp application. */ if ((LP_F(minor) & LP_ABORTOPEN) && !(file->f_flags & O_NONBLOCK)) { int status; + if (mutex_lock_interruptible(&lp_table[minor].port_mutex)) { + ret =3D -EINTR; + goto out; + } lp_claim_parport_or_block(&lp_table[minor]); status =3D r_str(minor); lp_release_parport(&lp_table[minor]); + mutex_unlock(&lp_table[minor].port_mutex); if (status & LP_POUTPA) { printk(KERN_INFO "lp%d out of paper\n", minor); LP_F(minor) &=3D ~LP_BUSY; @@ -547,6 +552,10 @@ static int lp_open(struct inode *inode, struct file *f= ile) goto out; } /* Determine if the peripheral supports ECP mode */ + if (mutex_lock_interruptible(&lp_table[minor].port_mutex)) { + ret =3D -EINTR; + goto out; + } lp_claim_parport_or_block(&lp_table[minor]); if ((lp_table[minor].dev->port->modes & PARPORT_MODE_ECP) && !parport_negotiate(lp_table[minor].dev->port, @@ -559,6 +568,7 @@ static int lp_open(struct inode *inode, struct file *fi= le) /* Leave peripheral in compatibility mode */ parport_negotiate(lp_table[minor].dev->port, IEEE1284_MODE_COMPAT); lp_release_parport(&lp_table[minor]); + mutex_unlock(&lp_table[minor].port_mutex); lp_table[minor].current_mode =3D IEEE1284_MODE_COMPAT; out: mutex_unlock(&lp_mutex); @@ -569,10 +579,13 @@ static int lp_release(struct inode *inode, struct fil= e *file) { unsigned int minor =3D iminor(inode); =20 + /* ->release should never fail. Use uninterruptible mutex variant */ + mutex_lock(&lp_table[minor].port_mutex); lp_claim_parport_or_block(&lp_table[minor]); parport_negotiate(lp_table[minor].dev->port, IEEE1284_MODE_COMPAT); lp_table[minor].current_mode =3D IEEE1284_MODE_COMPAT; lp_release_parport(&lp_table[minor]); + mutex_unlock(&lp_table[minor].port_mutex); kfree(lp_table[minor].lp_buffer); lp_table[minor].lp_buffer =3D NULL; LP_F(minor) &=3D ~LP_BUSY; @@ -641,7 +654,10 @@ static int lp_do_ioctl(unsigned int minor, unsigned in= t cmd, return -EFAULT; break; case LPRESET: + if (mutex_lock_interruptible(&lp_table[minor].port_mutex)) + return -EINTR; lp_reset(minor); + mutex_unlock(&lp_table[minor].port_mutex); break; #ifdef LP_STATS case LPGETSTATS: --=20 2.39.2