Linux s390 Architecture development
 help / color / mirror / Atom feed
From: Alexandra Winter <wintera@linux.ibm.com>
To: sashiko-reviews@lists.linux.dev
Cc: linux-s390@vger.kernel.org, Vasily Gorbik <gor@linux.ibm.com>,
	Alexander Gordeev <agordeev@linux.ibm.com>,
	Heiko Carstens <hca@linux.ibm.com>
Subject: Re: [PATCH net] s390/ism: Fix UAF of sba and ieq during ism_dev_exit()
Date: Thu, 6 Aug 2026 18:32:17 +0200	[thread overview]
Message-ID: <466273ca-fdfc-4bde-b5c0-371ccef6718a@linux.ibm.com> (raw)
In-Reply-To: <20260806131106.077EC1F00A3A@smtp.kernel.org>



On 06.08.26 15:11, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
> 
> New issues:
> - [Critical] The patch unconditionally frees DMA memory even if the firmware command to unregister the structures fails, potentially causing the hardware to perform DMA into freed pages.
> 
> Pre-existing issues:
> - [High] Incomplete fix: The `ism_dev_init()` error path frees the SBA data structure before unregistering the interrupt handler, preserving the Use-After-Free/NULL pointer dereference race condition.
> - [High] The interrupt handler is registered before the DMA structures it depends on are fully initialized, leading to a possible NULL pointer dereference on early/spurious interrupts.
> --
> 
> --- Patch [1]: [PATCH net] s390/ism: Fix UAF of sba and ieq during ism_dev_exit() ---
> commit b7d428b60205e305c1f2fbb4f8ba1ff2da436f6f
> Author: Alexandra Winter <wintera@linux.ibm.com>
> 
> s390/ism: Fix UAF of sba and ieq during ism_dev_exit()
> 
> This commit fixes a use-after-free race condition in the device teardown
> path by draining ongoing interrupt handlers before freeing the internal
> shared memory data structures.
> 
>> diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c
>> --- a/drivers/s390/net/ism_drv.c
>> +++ b/drivers/s390/net/ism_drv.c
>> @@ -148,13 +148,16 @@ static int unregister_sba(struct ism_dev *ism)
>>  	if (ret && ret != ISM_ERROR)
>>  		return -EIO;
>>  
>> +	return 0;
>> +}
>> +
>> +static void ism_free_sba(struct ism_dev *ism)
>> +{
>>  	dma_free_coherent(&ism->pdev->dev, PAGE_SIZE,
>>  			  ism->sba, ism->sba_dma_addr);
>>  
>>  	ism->sba = NULL;
>>  	ism->sba_dma_addr = 0;
>> -
>> -	return 0;
>>  }
> 
> [ ... ]
> 
>> @@ -585,9 +592,13 @@ static void ism_dev_exit(struct ism_dev *ism)
>>  {
>>  	struct pci_dev *pdev = ism->pdev;
>>  
>> +	/* ism will only generate new IRQs while ieq & sba are registered */
>>  	unregister_ieq(ism);
>>  	unregister_sba(ism);
> 
> [Severity: Critical]
> If unregister_ieq() or unregister_sba() fails (returning -EIO) due to a
> hardware or firmware error, the device may still be active and performing
> DMA to the SBA or IEQ memory regions.
> 
> By separating the free operations and calling them unconditionally here,
> could we be returning active DMA pages to the kernel allocator, leading to
> memory corruption?
> 


Cases where a bad return code from HW/FW can happen:
- Device is configured off or unplugged -> ISM_ERROR -> ok to free
- Still DMBs registered -> does not happen with today's kernel code, afaict
  I plan to make this more robust for future dibs clients.
- Broken FW

=> We cannot create a scenario today where -EIO will be returned.



>> +	/* drain ongoing irpt handlers */
>>  	free_irq(pci_irq_vector(pdev, 0), ism);
>> +	ism_free_ieq(ism);
>> +	ism_free_sba(ism);
>>  	pci_free_irq_vectors(pdev);
>>  }
> 
> [ ... ]
> 
>> @@ -573,6 +579,7 @@ static int ism_dev_init(struct ism_dev *ism)
>>  
>>  unreg_sba:
>>  	unregister_sba(ism);
>> +	ism_free_sba(ism);
>>  free_irq:
>>  	free_irq(pci_irq_vector(pdev, 0), ism);
> 
> [Severity: High]
> This is a pre-existing issue, but I noticed the error path here frees the
> SBA data structure before calling free_irq().
> 
> If register_ieq() fails during initialization, could a concurrent interrupt
> fire after ism_free_sba() but before free_irq(), causing ism_handle_irq()
> to dereference a NULL ism->sba pointer?


No interrupts are generated before SBA AND IEQ are successfully registered.
So this scenario is not possible for this error path.


> 
> Additionally, this is another pre-existing issue, but looking earlier in
> ism_dev_init():
> 
> ism_dev_init() {
>     ...
>     ret = request_irq(pci_irq_vector(pdev, 0), ism_handle_irq, 0,
>                       pci_name(pdev), ism);
>     if (ret)
>         goto free_vectors;
> 
>     ret = register_sba(ism);
>     ...
> }
> 
> [Severity: High]
> Since request_irq() enables the interrupt handler before register_sba()
> allocates and assigns the data structures, what happens if an early or
> spurious MSI interrupt fires during this window?
> 
> Will ism_handle_irq() unconditionally dereference the uninitialized
> ism->sba pointer upon entry?
> 

No interrupts are generated before SBA AND IEQ are successfully registered.

I will add comments in a cleanup patch.





  reply	other threads:[~2026-08-06 16:32 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-05 13:10 [PATCH net] s390/ism: Fix UAF of sba and ieq during ism_dev_exit() Alexandra Winter
2026-08-06 13:11 ` sashiko-bot
2026-08-06 16:32   ` Alexandra Winter [this message]
2026-08-06 16:50 ` patchwork-bot+netdevbpf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=466273ca-fdfc-4bde-b5c0-371ccef6718a@linux.ibm.com \
    --to=wintera@linux.ibm.com \
    --cc=agordeev@linux.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=linux-s390@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox