Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spi: axi-spi-engine: fix use after free after timeout #2292

Merged
merged 1 commit into from
Oct 20, 2023

Conversation

dlech
Copy link
Collaborator

@dlech dlech commented Oct 17, 2023

This fixes a use after free that can happen if the watchdog timer times out on an SPI message then another message is attempted.

The following struct spi_engine members point to memory managed by the spi framework

struct spi_message *msg;
struct spi_transfer *tx_xfer;
const uint8_t *tx_buf;
struct spi_transfer *rx_xfer;
uint8_t *rx_buf;

During normal operation, tx_xfer and rx_xfer set to NULL by spi_engine_xfer_next() when the last xfer of a message is completed. However, this code path is not taken when the watchdog timer times out and therefore tx_xfer and rx_xfer are not set to NULL and still point to memory that gets freed by spi_finalize_current_message().

When the next message is attempted, spi_engine_transfer_one() will call spi_engine_xfer_next() with the old pointers and will attempt to dereference them. This can cause a crash.

To fix this, always set tx_xfer and rx_xfer to NULL before calling spi_finalize_current_message().

Fixes: fde5597 ("spi: axi-spi-engine: Add watchdog timer")

Fixes: #2287

This fixes a use after free that can happen if the watchdog timer
times out on an SPI message then another message is attempted.

The following struct spi_engine members point to memory managed by the
spi framework

	struct spi_message *msg;
	struct spi_transfer *tx_xfer;
	const uint8_t *tx_buf;
	struct spi_transfer *rx_xfer;
	uint8_t *rx_buf;

During normal operation, tx_xfer and rx_xfer set to NULL by
spi_engine_xfer_next() when the last xfer of a message is completed.
However, this code path is not taken when the watchdog timer times out
and therefore tx_xfer and rx_xfer are not set to NULL and still point
to memory that gets freed by spi_finalize_current_message().

When the next message is attempted, spi_engine_transfer_one() will
call spi_engine_xfer_next() with the old pointers and will attempt to
dereference them. This can cause a crash.

To fix this, always set tx_xfer and rx_xfer to NULL before calling
spi_finalize_current_message().

Fixes: fde5597 ("spi: axi-spi-engine: Add watchdog timer")
Signed-off-by: David Lechner <dlechner@baylibre.com>
Copy link
Collaborator

@nunojsa nunojsa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! Could you see if this fix is applicable upstream? It might be...

@dlech
Copy link
Collaborator Author

dlech commented Oct 18, 2023

Great! Could you see if this fix is applicable upstream? It might be...

I checked and the watchdog timer patch has not been upstreamed.

@nunojsa
Copy link
Collaborator

nunojsa commented Oct 20, 2023

I checked and the watchdog timer patch has not been upstreamed.

Alright... I guess it will be then part of the work in syncing up this driver (plus offload support). I'll then merge this and it can be squashed with the watchdog patch when upstreaming.

@nunojsa nunojsa merged commit 67a2d15 into master Oct 20, 2023
12 checks passed
@nunojsa nunojsa deleted the dlech/fix-spi-engine-crash-after-timeout branch October 20, 2023 07:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

kernel oops in spi engine after read timeout
4 participants