Skip to content

Commit a5ce845

Browse files
committed
Merge: spi: Fix null dereference on suspend
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/4651 JIRA: https://issues.redhat.com/browse/RHEL-38218 CVE: CVE-2023-52749 Signed-off-by: Andrew Halaney <ahalaney@redhat.com> Approved-by: Brian Masney <bmasney@redhat.com> Approved-by: Eric Chanudet <echanude@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Lucas Zampieri <lzampier@redhat.com>
2 parents 6535f94 + 1d4e3a6 commit a5ce845

File tree

2 files changed

+40
-17
lines changed

2 files changed

+40
-17
lines changed

drivers/spi/spi.c

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3302,33 +3302,52 @@ void spi_unregister_controller(struct spi_controller *ctlr)
33023302
}
33033303
EXPORT_SYMBOL_GPL(spi_unregister_controller);
33043304

3305+
static inline int __spi_check_suspended(const struct spi_controller *ctlr)
3306+
{
3307+
return ctlr->flags & SPI_CONTROLLER_SUSPENDED ? -ESHUTDOWN : 0;
3308+
}
3309+
3310+
static inline void __spi_mark_suspended(struct spi_controller *ctlr)
3311+
{
3312+
mutex_lock(&ctlr->bus_lock_mutex);
3313+
ctlr->flags |= SPI_CONTROLLER_SUSPENDED;
3314+
mutex_unlock(&ctlr->bus_lock_mutex);
3315+
}
3316+
3317+
static inline void __spi_mark_resumed(struct spi_controller *ctlr)
3318+
{
3319+
mutex_lock(&ctlr->bus_lock_mutex);
3320+
ctlr->flags &= ~SPI_CONTROLLER_SUSPENDED;
3321+
mutex_unlock(&ctlr->bus_lock_mutex);
3322+
}
3323+
33053324
int spi_controller_suspend(struct spi_controller *ctlr)
33063325
{
3307-
int ret;
3326+
int ret = 0;
33083327

33093328
/* Basically no-ops for non-queued controllers */
3310-
if (!ctlr->queued)
3311-
return 0;
3312-
3313-
ret = spi_stop_queue(ctlr);
3314-
if (ret)
3315-
dev_err(&ctlr->dev, "queue stop failed\n");
3329+
if (ctlr->queued) {
3330+
ret = spi_stop_queue(ctlr);
3331+
if (ret)
3332+
dev_err(&ctlr->dev, "queue stop failed\n");
3333+
}
33163334

3335+
__spi_mark_suspended(ctlr);
33173336
return ret;
33183337
}
33193338
EXPORT_SYMBOL_GPL(spi_controller_suspend);
33203339

33213340
int spi_controller_resume(struct spi_controller *ctlr)
33223341
{
3323-
int ret;
3324-
3325-
if (!ctlr->queued)
3326-
return 0;
3342+
int ret = 0;
33273343

3328-
ret = spi_start_queue(ctlr);
3329-
if (ret)
3330-
dev_err(&ctlr->dev, "queue restart failed\n");
3344+
__spi_mark_resumed(ctlr);
33313345

3346+
if (ctlr->queued) {
3347+
ret = spi_start_queue(ctlr);
3348+
if (ret)
3349+
dev_err(&ctlr->dev, "queue restart failed\n");
3350+
}
33323351
return ret;
33333352
}
33343353
EXPORT_SYMBOL_GPL(spi_controller_resume);
@@ -4090,8 +4109,7 @@ static void __spi_transfer_message_noqueue(struct spi_controller *ctlr, struct s
40904109
ctlr->cur_msg = msg;
40914110
ret = __spi_pump_transfer_message(ctlr, msg, was_busy);
40924111
if (ret)
4093-
goto out;
4094-
4112+
dev_err(&ctlr->dev, "noqueue transfer failed\n");
40954113
ctlr->cur_msg = NULL;
40964114
ctlr->fallback = false;
40974115

@@ -4107,7 +4125,6 @@ static void __spi_transfer_message_noqueue(struct spi_controller *ctlr, struct s
41074125
spi_idle_runtime_pm(ctlr);
41084126
}
41094127

4110-
out:
41114128
mutex_unlock(&ctlr->io_mutex);
41124129
}
41134130

@@ -4130,6 +4147,11 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message)
41304147
int status;
41314148
struct spi_controller *ctlr = spi->controller;
41324149

4150+
if (__spi_check_suspended(ctlr)) {
4151+
dev_warn_once(&spi->dev, "Attempted to sync while suspend\n");
4152+
return -ESHUTDOWN;
4153+
}
4154+
41334155
status = __spi_validate(spi, message);
41344156
if (status != 0)
41354157
return status;

include/linux/spi/spi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,7 @@ struct spi_controller {
561561
#define SPI_CONTROLLER_MUST_TX BIT(4) /* Requires tx */
562562

563563
#define SPI_MASTER_GPIO_SS BIT(5) /* GPIO CS must select slave */
564+
#define SPI_CONTROLLER_SUSPENDED BIT(6) /* Currently suspended */
564565

565566
/* Flag indicating if the allocation of this struct is devres-managed */
566567
bool devm_allocated;

0 commit comments

Comments
 (0)