| Message ID | 20260902-i2c_double_free-v1-1-0f582ef32e55@oss.qualcomm.com |
|---|---|
| State | New |
| Headers | show |
| Series | [v1] i2c: qcom-geni: Clear stale TX/RX buffer pointers after GPI cleanup | expand |
Hi On 02-09-2026 20:15, Aniket Randive wrote: > The TX and RX buffer pointers are reused across messages in a GPI > transfer. After a buffer is unmapped and freed, the pointer is left > unchanged. A later message can reuse the stale pointer in the cleanup > path, causing a double unmap and double free. > > This can happen when a READ message is followed by a WRITE message, > leaving a stale RX buffer pointer behind. A similar issue can occur for > the TX buffer when a mapping or allocation failure prevents the pointer > from being updated before the error path runs. > > Clear tx_buf and rx_buf after unmapping and freeing them. This ensures > later iterations and error paths only see a valid buffer pointer or > NULL, preventing double unmap and double free issues. > > Signed-off-by: Aniket Randive <aniket.randive@oss.qualcomm.com> > --- > drivers/i2c/busses/i2c-qcom-geni.c | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c > index 942cfeee99ba..4965872b47d5 100644 > --- a/drivers/i2c/busses/i2c-qcom-geni.c > +++ b/drivers/i2c/busses/i2c-qcom-geni.c > @@ -911,10 +911,13 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i > goto err; > } > > - if (!gi2c->is_tx_multi_desc_xfer) > + if (!gi2c->is_tx_multi_desc_xfer) { > geni_i2c_gpi_unmap(gi2c, &msgs[i], tx_buf, tx_addr, rx_buf, rx_addr); > - else if (tx_multi_xfer->unmap_msg_cnt != tx_multi_xfer->irq_cnt) > + tx_buf = NULL; > + rx_buf = NULL; > + } else if (tx_multi_xfer->unmap_msg_cnt != tx_multi_xfer->irq_cnt) { > geni_i2c_gpi_multi_desc_unmap(gi2c, msgs, &peripheral); > + } > } > Reviewed-by: Praveen Talari <praveen.talari@oss.qualcomm.com> Thanks, Praveen Talari > return num; > > --- > base-commit: 89c07d98716a13454ec3fd9f97689e812cc71bd4 > change-id: 20260901-i2c_double_free-09ab0b97e61d > > Best regards, > -- > Aniket Randive <aniket.randive@oss.qualcomm.com> > >
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index 942cfeee99ba..4965872b47d5 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -911,10 +911,13 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i goto err; } - if (!gi2c->is_tx_multi_desc_xfer) + if (!gi2c->is_tx_multi_desc_xfer) { geni_i2c_gpi_unmap(gi2c, &msgs[i], tx_buf, tx_addr, rx_buf, rx_addr); - else if (tx_multi_xfer->unmap_msg_cnt != tx_multi_xfer->irq_cnt) + tx_buf = NULL; + rx_buf = NULL; + } else if (tx_multi_xfer->unmap_msg_cnt != tx_multi_xfer->irq_cnt) { geni_i2c_gpi_multi_desc_unmap(gi2c, msgs, &peripheral); + } } return num;
The TX and RX buffer pointers are reused across messages in a GPI transfer. After a buffer is unmapped and freed, the pointer is left unchanged. A later message can reuse the stale pointer in the cleanup path, causing a double unmap and double free. This can happen when a READ message is followed by a WRITE message, leaving a stale RX buffer pointer behind. A similar issue can occur for the TX buffer when a mapping or allocation failure prevents the pointer from being updated before the error path runs. Clear tx_buf and rx_buf after unmapping and freeing them. This ensures later iterations and error paths only see a valid buffer pointer or NULL, preventing double unmap and double free issues. Signed-off-by: Aniket Randive <aniket.randive@oss.qualcomm.com> --- drivers/i2c/busses/i2c-qcom-geni.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) --- base-commit: 89c07d98716a13454ec3fd9f97689e812cc71bd4 change-id: 20260901-i2c_double_free-09ab0b97e61d Best regards, -- Aniket Randive <aniket.randive@oss.qualcomm.com>