diff mbox series

[iwl-net] idpf: fix NULL pointer dereference and memory leak in interrupt request

Message ID 20260904091827.911123-1-zhangyunfei1@kylinos.cn
State Under Review
Delegated to: Anthony Nguyen
Headers show
Series [iwl-net] idpf: fix NULL pointer dereference and memory leak in interrupt request | expand

Commit Message

Zhang Yunfei Sept. 4, 2026, 9:18 a.m. UTC
The kasprintf() call in idpf_vport_intr_req_irq() can return NULL on
memory pressure, but the result is passed directly to request_irq()
without a NULL check. The IRQ core then stores this pointer as
action->name and dereferences it later from /proc/interrupts and
procfs, leading to a NULL pointer dereference.

Add a NULL check after kasprintf() and bail out with -ENOMEM.

Additionally, when request_irq() fails, request_threaded_irq() frees
the irqaction itself without taking ownership of the name string, so
the caller-allocated name is leaked. Free it on the error path only.
On the success path the name is owned by the irq action and released
later via kfree(free_irq(...)) in the cleanup loop, so it must not be
freed here.

Fixes: d4d558718266 ("idpf: initialize interrupts and enable vport")
Cc: stable@vger.kernel.org # 6.7
Signed-off-by: Zhang Yunfei <zhangyunfei1@kylinos.cn>
---
 drivers/net/ethernet/intel/idpf/idpf_txrx.c | 5 +++++
 1 file changed, 5 insertions(+)

Comments

Simon Horman Sept. 8, 2026, 9:25 a.m. UTC | #1
On Fri, Sep 04, 2026 at 05:18:27PM +0800, Zhang Yunfei wrote:
> The kasprintf() call in idpf_vport_intr_req_irq() can return NULL on
> memory pressure, but the result is passed directly to request_irq()
> without a NULL check. The IRQ core then stores this pointer as
> action->name and dereferences it later from /proc/interrupts and
> procfs, leading to a NULL pointer dereference.
> 
> Add a NULL check after kasprintf() and bail out with -ENOMEM.
> 
> Additionally, when request_irq() fails, request_threaded_irq() frees
> the irqaction itself without taking ownership of the name string, so
> the caller-allocated name is leaked. Free it on the error path only.
> On the success path the name is owned by the irq action and released
> later via kfree(free_irq(...)) in the cleanup loop, so it must not be
> freed here.
> 
> Fixes: d4d558718266 ("idpf: initialize interrupts and enable vport")
> Cc: stable@vger.kernel.org # 6.7
> Signed-off-by: Zhang Yunfei <zhangyunfei1@kylinos.cn>

Reviewed-by: Simon Horman <horms@kernel.org>
Aleksandr Loktionov Sept. 8, 2026, 1:14 p.m. UTC | #2
> -----Original Message-----
> From: Zhang Yunfei <zhangyunfei1@kylinos.cn>
> Sent: Friday, September 4, 2026 11:18 AM
> To: Nguyen, Anthony L <anthony.l.nguyen@intel.com>
> Cc: Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; intel-wired-
> lan@lists.osuosl.org; netdev@vger.kernel.org; linux-
> kernel@vger.kernel.org; stable@vger.kernel.org
> Subject: [PATCH iwl-net] idpf: fix NULL pointer dereference and memory
> leak in interrupt request
> 
> The kasprintf() call in idpf_vport_intr_req_irq() can return NULL on
> memory pressure, but the result is passed directly to request_irq()
> without a NULL check. The IRQ core then stores this pointer as
> action->name and dereferences it later from /proc/interrupts and
> procfs, leading to a NULL pointer dereference.
> 
> Add a NULL check after kasprintf() and bail out with -ENOMEM.
> 
> Additionally, when request_irq() fails, request_threaded_irq() frees
> the irqaction itself without taking ownership of the name string, so
> the caller-allocated name is leaked. Free it on the error path only.
> On the success path the name is owned by the irq action and released
> later via kfree(free_irq(...)) in the cleanup loop, so it must not be
> freed here.
> 
> Fixes: d4d558718266 ("idpf: initialize interrupts and enable vport")
> Cc: stable@vger.kernel.org # 6.7
> Signed-off-by: Zhang Yunfei <zhangyunfei1@kylinos.cn>
> ---
>  drivers/net/ethernet/intel/idpf/idpf_txrx.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> index 24b91be25676..86dedf5c1c09 100644
> --- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> +++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> @@ -4063,12 +4063,17 @@ static int idpf_vport_intr_req_irq(struct
> idpf_vport *vport,
> 
>  		name = kasprintf(GFP_KERNEL, "%s-%s-%s-%d", drv_name,
> if_name,
>  				 vec_name, vector);
> +		if (!name) {
> +			err = -ENOMEM;
> +			goto free_q_irqs;
> +		}
> 
>  		err = request_irq(irq_num, idpf_vport_intr_clean_queues,
> 0,
>  				  name, q_vector);
>  		if (err) {
>  			netdev_err(vport->netdev,
>  				   "Request_irq failed, error: %d\n", err);
> +			kfree(name);
>  			goto free_q_irqs;
>  		}
> 
> --
> 2.25.1

Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Salin, Samuel Oct. 5, 2026, 4:33 p.m. UTC | #3
> -----Original Message-----
> From: Loktionov, Aleksandr <aleksandr.loktionov@intel.com>
> Sent: Tuesday, September 8, 2026 6:15 AM
> To: Zhang Yunfei <zhangyunfei1@kylinos.cn>; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>
> Cc: Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; intel-wired-
> lan@lists.osuosl.org; netdev@vger.kernel.org; linux-kernel@vger.kernel.org;
> stable@vger.kernel.org
> Subject: RE: [PATCH iwl-net] idpf: fix NULL pointer dereference and memory
> leak in interrupt request
> 
> 
> 
> > -----Original Message-----
> > From: Zhang Yunfei <zhangyunfei1@kylinos.cn>
> > Sent: Friday, September 4, 2026 11:18 AM
> > To: Nguyen, Anthony L <anthony.l.nguyen@intel.com>
> > Cc: Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; intel-wired-
> > lan@lists.osuosl.org; netdev@vger.kernel.org; linux-
> > kernel@vger.kernel.org; stable@vger.kernel.org
> > Subject: [PATCH iwl-net] idpf: fix NULL pointer dereference and memory
> > leak in interrupt request
> >
> > The kasprintf() call in idpf_vport_intr_req_irq() can return NULL on
> > memory pressure, but the result is passed directly to request_irq()
> > without a NULL check. The IRQ core then stores this pointer as
> > action->name and dereferences it later from /proc/interrupts and
> > procfs, leading to a NULL pointer dereference.
> >
> > Add a NULL check after kasprintf() and bail out with -ENOMEM.
> >
> > Additionally, when request_irq() fails, request_threaded_irq() frees
> > the irqaction itself without taking ownership of the name string, so
> > the caller-allocated name is leaked. Free it on the error path only.
> > On the success path the name is owned by the irq action and released
> > later via kfree(free_irq(...)) in the cleanup loop, so it must not be
> > freed here.
> >
> > Fixes: d4d558718266 ("idpf: initialize interrupts and enable vport")
> > Cc: stable@vger.kernel.org # 6.7
> > Signed-off-by: Zhang Yunfei <zhangyunfei1@kylinos.cn>
> > ---
> >  drivers/net/ethernet/intel/idpf/idpf_txrx.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> > b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> > index 24b91be25676..86dedf5c1c09 100644
> > --- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> > +++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
> > @@ -4063,12 +4063,17 @@ static int idpf_vport_intr_req_irq(struct
> > idpf_vport *vport,
> >
> >  		name = kasprintf(GFP_KERNEL, "%s-%s-%s-%d", drv_name,
> if_name,
> >  				 vec_name, vector);
> > +		if (!name) {
> > +			err = -ENOMEM;
> > +			goto free_q_irqs;
> > +		}
> >
> >  		err = request_irq(irq_num, idpf_vport_intr_clean_queues, 0,
> >  				  name, q_vector);
> >  		if (err) {
> >  			netdev_err(vport->netdev,
> >  				   "Request_irq failed, error: %d\n", err);
> > +			kfree(name);
> >  			goto free_q_irqs;
> >  		}
> >
> > --
> > 2.25.1
> 
> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>

Tested-by: Samuel Salin <Samuel.salin@intel.com>
diff mbox series

Patch

diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
index 24b91be25676..86dedf5c1c09 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -4063,12 +4063,17 @@  static int idpf_vport_intr_req_irq(struct idpf_vport *vport,
 
 		name = kasprintf(GFP_KERNEL, "%s-%s-%s-%d", drv_name, if_name,
 				 vec_name, vector);
+		if (!name) {
+			err = -ENOMEM;
+			goto free_q_irqs;
+		}
 
 		err = request_irq(irq_num, idpf_vport_intr_clean_queues, 0,
 				  name, q_vector);
 		if (err) {
 			netdev_err(vport->netdev,
 				   "Request_irq failed, error: %d\n", err);
+			kfree(name);
 			goto free_q_irqs;
 		}