From 4b4068c948ea4fd764df549aedb70d0f698491c3 Mon Sep 17 00:00:00 2001 From: Armando Visconti Date: Thu, 13 May 2021 18:24:25 +0200 Subject: [PATCH] kernel/device: add arg checking in z_device_ready() If this call receives an invalid device pointer as argument it assumes that the `device` is not ready for usage. This routine is currently called by two device specific APIs: - device_usable_check(const struct device *dev) - device_is_ready(const struct device *dev) The device-specific APIs documentation claims that these two routines must be called with a device pointer captured from DEVICE_DT_GET(). So passing NULL is a violation of the rule. Nevertheless, is quite common in drivers to assign NULL to a device pointer if the corresponding DT property has not been found (e.g. a not used gpio interrupt declaration for a given device instance) and seems legit to interpret this condition same as the device is not ready for usage. Signed-off-by: Armando Visconti --- include/device.h | 7 ++++--- kernel/device.c | 8 ++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/device.h b/include/device.h index 3216d54689c..9ef081cbd03 100644 --- a/include/device.h +++ b/include/device.h @@ -581,8 +581,8 @@ static inline int z_device_usable_check(const struct device *dev) * distinct error values that identify the reason if it cannot. * * @retval 0 if the device is usable. - * @retval -ENODEV if the device has not been initialized, or the - * initialization failed. + * @retval -ENODEV if the device has not been initialized, the device pointer + * is NULL or the initialization failed. * @retval other negative error codes to indicate additional conditions that * make the device unusable. */ @@ -606,7 +606,8 @@ static inline int z_impl_device_usable_check(const struct device *dev) * @param dev pointer to the device in question. * * @retval true if the device is ready for use. - * @retval false if the device is not ready for use. + * @retval false if the device is not ready for use or if a NULL device pointer + * is passed as argument. */ static inline bool device_is_ready(const struct device *dev) { diff --git a/kernel/device.c b/kernel/device.c index e30f3e96c50..5f3a962beb1 100644 --- a/kernel/device.c +++ b/kernel/device.c @@ -163,6 +163,14 @@ size_t z_device_get_all_static(struct device const **devices) bool z_device_ready(const struct device *dev) { + /* + * if an invalid device pointer is passed as argument, this call + * reports the `device` as not ready for usage. + */ + if (dev == NULL) { + return false; + } + return dev->state->initialized && (dev->state->init_res == 0U); }