spi: Check presence the of ->transfer[_xxx]() before registering a controller

Right now, no checks are done on the presence of a ->transfer[_xxx]()
method, which can lead to a NULL pointer dereference when someone
starts sending something on the bus.

Do the check at registration time and refuse to add the controller if
all ->transfer[_xxx]() pointers are NULL.

Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Boris Brezillon 2018-04-11 00:44:30 +02:00 коммит произвёл Mark Brown
Родитель 0d7412ed1f
Коммит bdf3a3b59a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 24D68B725D5487D0
1 изменённых файлов: 21 добавлений и 0 удалений

Просмотреть файл

@ -2068,6 +2068,19 @@ static int of_spi_register_master(struct spi_controller *ctlr)
} }
#endif #endif
static int spi_controller_check_ops(struct spi_controller *ctlr)
{
/*
* The controller must at least implement one of the ->transfer()
* hooks.
*/
if (!ctlr->transfer && !ctlr->transfer_one &&
!ctlr->transfer_one_message)
return -EINVAL;
return 0;
}
/** /**
* spi_register_controller - register SPI master or slave controller * spi_register_controller - register SPI master or slave controller
* @ctlr: initialized master, originally from spi_alloc_master() or * @ctlr: initialized master, originally from spi_alloc_master() or
@ -2101,6 +2114,14 @@ int spi_register_controller(struct spi_controller *ctlr)
if (!dev) if (!dev)
return -ENODEV; return -ENODEV;
/*
* Make sure all necessary hooks are implemented before registering
* the SPI controller.
*/
status = spi_controller_check_ops(ctlr);
if (status)
return status;
if (!spi_controller_is_slave(ctlr)) { if (!spi_controller_is_slave(ctlr)) {
status = of_spi_register_master(ctlr); status = of_spi_register_master(ctlr);
if (status) if (status)