Skip to contentSkip to conversation

s390/ism: folio_put() after error

PATCH Applied Alexandra Winter 4 participants 6 messages Sep 2 – Sep 4

Subsystems (4)
lore
Share & tools
lore

Alexandra Winter

author maintainer
#0 lore raw

PATCH 1/1 s390/ism: folio_put() after error

dmb->cpu_addr was allocated via folio_alloc(). Use folio_put() instead of kfree() in the error exit of ism_alloc_dmb() to avoid slab allocator corruption.

While at it, reset dmb->cpu_addr after folio_put to avoid unintentional UAF by future callers.

Fixes 83781384a96b ("s390/ism: Properly fix receive message buffer allocation")
---
 drivers/s390/net/ism_drv.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/s390/net/ism_drv.c +3 -1
index 242da20f27e0..035b233abb4e 100644
@@ -231,6 +231,7 @@ static void ism_free_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)
 	dma_unmap_page(&ism->pdev->dev, dmb->dma_addr, dmb->dmb_len,
 		       DMA_FROM_DEVICE);
 	folio_put(virt_to_folio(dmb->cpu_addr));
+	dmb->cpu_addr = NULL;
 }
 
 static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)
@@ -274,7 +275,8 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)
 	return 0;
 
 out_free:
-	kfree(dmb->cpu_addr);
+	folio_put(folio);
+	dmb->cpu_addr = NULL;
 out_bit:
 	clear_bit(dmb->idx, ism->sba_bitmap);
 	return rc;
Signature · 1 line
2.53.0
Reviewed-by on v1 1/1
#1 lore raw
Quoted 26 lines · Alexandra Winter

dmb->cpu_addr was allocated via folio_alloc(). Use folio_put() instead of kfree() in the error exit of ism_alloc_dmb() to avoid slab allocator corruption.

While at it, reset dmb->cpu_addr after folio_put to avoid unintentional UAF by future callers.

Fixes 83781384a96b ("s390/ism: Properly fix receive message buffer allocation")
---
 drivers/s390/net/ism_drv.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/s390/net/ism_drv.c +1 -0
index 242da20f27e0..035b233abb4e 100644
@@ -231,6 +231,7 @@ static void ism_free_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)
 	dma_unmap_page(&ism->pdev->dev, dmb->dma_addr, dmb->dmb_len,
 		       DMA_FROM_DEVICE);
 	folio_put(virt_to_folio(dmb->cpu_addr));
+	dmb->cpu_addr = NULL;
 }
 
 static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)

drivers/s390/net/ism_drv.c static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb) · line 282

Quoted 9 lines
drivers/s390/net/ism_drv.c +2 -1
@@ -274,7 +275,8 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)
 	return 0;
 
 out_free:
-	kfree(dmb->cpu_addr);
+	folio_put(folio);
+	dmb->cpu_addr = NULL;
 out_bit:
 	clear_bit(dmb->idx, ism->sba_bitmap);
 	return rc;

Hi Alexandra,

thank you for catching and addressing these flaws in my patch. Feel free to accept my

Thanks!

#2 lore raw
In reply to Alexandra Winter
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Missing __GFP_ZERO in folio_alloc() causes uninitialized kernel memory to be exposed in the receive message buffer. --

commit d942ada155dde57df3b8bd6857db438603cbd218
Author: Alexandra Winter <[email protected]>

s390/ism: folio_put() after error

This commit uses folio_put() instead of kfree() in the error path of ism_alloc_dmb() to prevent slab allocator corruption. It also sets dmb->cpu_addr to NULL after freeing to prevent a potential use-after-free.

Fixes 83781384a96b ("s390/ism: Properly fix receive message buffer allocation")
Quoted 4 lines
drivers/s390/net/ism_drv.c +0 -0
index 242da20f27e0e..035b233abb4e9 100644

[ ... ]

drivers/s390/net/ism_drv.c static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb) · line 278

Quoted 6 lines
drivers/s390/net/ism_drv.c +1 -1
@@ -274,7 +275,8 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)
 	return 0;
 
 out_free:
-	kfree(dmb->cpu_addr);
+	folio_put(folio);

[Severity: Critical]
This isn't a bug introduced by this patch, but the previous replacement of dma_alloc_coherent() with folio_alloc() removed the implicit zero-initialization of the Direct Message Buffer (DMB).

Looking at the allocation earlier in ism_alloc_dmb():

drivers/s390/net/ism_drv.c:ism_alloc_dmb() {
        ...
        folio = folio_alloc(GFP_KERNEL | __GFP_NOWARN | __GFP_NOMEMALLOC |
                            __GFP_NORETRY, get_order(dmb->dmb_len));
        ...
}

Does this missing __GFP_ZERO leak uninitialized host kernel memory to an untrusted remote peer?

A remote, unprivileged peer partition can trigger an SMC connection establishment via smcd_new_buf_create() -> smc_ism_register_dmb(). This causes the local host to allocate and map the DMB memory without zero-filling it locally before the peer partition gains access to it, potentially exposing uninitialized memory across the virtual machine or LPAR boundary.

Quoted 4 lines
drivers/s390/net/ism_drv.c +1 -0
+	dmb->cpu_addr = NULL;
 out_bit:
 	clear_bit(dmb->idx, ism->sba_bitmap);
 	return rc;
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
author maintainer
#3 lore raw
Quoted 43 lines · On 03.09.26 16:37, [email protected] wrote:

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Missing __GFP_ZERO in folio_alloc() causes uninitialized kernel memory to be exposed in the receive message buffer. --

commit d942ada155dde57df3b8bd6857db438603cbd218
Author: Alexandra Winter <[email protected]>

s390/ism: folio_put() after error

This commit uses folio_put() instead of kfree() in the error path of ism_alloc_dmb() to prevent slab allocator corruption. It also sets dmb->cpu_addr to NULL after freeing to prevent a potential use-after-free.

Fixes 83781384a96b ("s390/ism: Properly fix receive message buffer allocation")
Quoted 4 lines
drivers/s390/net/ism_drv.c +0 -0
index 242da20f27e0e..035b233abb4e9 100644

[ ... ]

drivers/s390/net/ism_drv.c static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb) · line 278

Quoted 6 lines
drivers/s390/net/ism_drv.c +1 -1
@@ -274,7 +275,8 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)
 	return 0;
 
 out_free:
-	kfree(dmb->cpu_addr);
+	folio_put(folio);

[Severity: Critical]
This isn't a bug introduced by this patch, but the previous replacement of dma_alloc_coherent() with folio_alloc() removed the implicit zero-initialization of the Direct Message Buffer (DMB).

Looking at the allocation earlier in ism_alloc_dmb():

drivers/s390/net/ism_drv.c:ism_alloc_dmb() {
        ...
        folio = folio_alloc(GFP_KERNEL | __GFP_NOWARN | __GFP_NOMEMALLOC |
                            __GFP_NORETRY, get_order(dmb->dmb_len));
        ...
}
Quoted 3 lines

Does this missing __GFP_ZERO leak uninitialized host kernel memory to an untrusted remote peer?

This is actually already on my ToDo list.
See also my discussion with Julian on 12.08.2026 about
Re: [PATCH v2 1/6] dibs: remove __GFP_ZERO from loopback

Quoted 12 lines

A remote, unprivileged peer partition can trigger an SMC connection establishment via smcd_new_buf_create() -> smc_ism_register_dmb(). This causes the local host to allocate and map the DMB memory without zero-filling it locally before the peer partition gains access to it, potentially exposing uninitialized memory across the virtual machine or LPAR boundary.

Quoted 4 lines
drivers/s390/net/ism_drv.c +1 -0
+	dmb->cpu_addr = NULL;
 out_bit:
 	clear_bit(dmb->idx, ism->sba_bitmap);
 	return rc;
author maintainer
#4 lore raw

Corrected To Julian

Quoted 69 lines · Alexandra Winter
Quoted 43 lines · On 03.09.26 16:37, [email protected] wrote:

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Missing __GFP_ZERO in folio_alloc() causes uninitialized kernel memory to be exposed in the receive message buffer. --

commit d942ada155dde57df3b8bd6857db438603cbd218
Author: Alexandra Winter <[email protected]>

s390/ism: folio_put() after error

This commit uses folio_put() instead of kfree() in the error path of ism_alloc_dmb() to prevent slab allocator corruption. It also sets dmb->cpu_addr to NULL after freeing to prevent a potential use-after-free.

Fixes 83781384a96b ("s390/ism: Properly fix receive message buffer allocation")
Quoted 4 lines
drivers/s390/net/ism_drv.c +0 -0
index 242da20f27e0e..035b233abb4e9 100644

[ ... ]

drivers/s390/net/ism_drv.c static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb) · line 278

Quoted 6 lines
drivers/s390/net/ism_drv.c +1 -1
@@ -274,7 +275,8 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)
 	return 0;
 
 out_free:
-	kfree(dmb->cpu_addr);
+	folio_put(folio);

[Severity: Critical]
This isn't a bug introduced by this patch, but the previous replacement of dma_alloc_coherent() with folio_alloc() removed the implicit zero-initialization of the Direct Message Buffer (DMB).

Looking at the allocation earlier in ism_alloc_dmb():

drivers/s390/net/ism_drv.c:ism_alloc_dmb() {
        ...
        folio = folio_alloc(GFP_KERNEL | __GFP_NOWARN | __GFP_NOMEMALLOC |
                            __GFP_NORETRY, get_order(dmb->dmb_len));
        ...
}
Quoted 3 lines

Does this missing __GFP_ZERO leak uninitialized host kernel memory to an untrusted remote peer?

This is actually already on my ToDo list.
See also my discussion with Julian on 12.08.2026 about
Re: [PATCH v2 1/6] dibs: remove __GFP_ZERO from loopback

Quoted 12 lines

A remote, unprivileged peer partition can trigger an SMC connection establishment via smcd_new_buf_create() -> smc_ism_register_dmb(). This causes the local host to allocate and map the DMB memory without zero-filling it locally before the peer partition gains access to it, potentially exposing uninitialized memory across the virtual machine or LPAR boundary.

Quoted 4 lines
drivers/s390/net/ism_drv.c +1 -0
+	dmb->cpu_addr = NULL;
 out_bit:
 	clear_bit(dmb->idx, ism->sba_bitmap);
 	return rc;
#5 lore raw
In reply to Alexandra Winter
This patch was applied to netdev/net.git (main) by Jakub Kicinski <[email protected]>:

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <[email protected]>:

Quoted 8 lines · On Wed, 2 Sep 2026 16:37:33 +0200 you wrote:

dmb->cpu_addr was allocated via folio_alloc(). Use folio_put() instead of kfree() in the error exit of ism_alloc_dmb() to avoid slab allocator corruption.

While at it, reset dmb->cpu_addr after folio_put to avoid unintentional UAF by future callers.

[...]

Here is the summary with links:
- [net] s390/ism: folio_put() after error

    https://git.kernel.org/netdev/net/c/907a56ab3eb8

You are awesome, thank you!

Signature · 2 lines
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html