ipc_service: Add endpoint registered check

Currently, it is possible to call various ipc_service functions
which take in an endpoint pointer (such as send, get_tx_buffer)
with an endpoint which has not been registered with the instance.
This leads to dereferencing a NULL pointer when the function tries
to access the api field of ept->instance.
This patch adds in multiple checks to ensure that the endpoint is
registered before continuing, one in the frontend, when ensures
that the ept->instance pointer is not NULL and one in the backend
which checks the value of the token pointer. If either of these fail,
we return -ENOENT.

Signed-off-by: Jackson Cooper-Driver <jackson.cooper---driver@amd.com>
This commit is contained in:
Jackson Cooper-Driver 2022-07-13 13:24:58 +01:00 committed by Carles Cufí
commit f06c06de07
4 changed files with 74 additions and 0 deletions

View file

@ -230,6 +230,7 @@ int ipc_service_register_endpoint(const struct device *instance,
* @retval -EIO when no backend is registered or send hook is missing from * @retval -EIO when no backend is registered or send hook is missing from
* backend. * backend.
* @retval -EINVAL when instance or endpoint is invalid. * @retval -EINVAL when instance or endpoint is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -EBADMSG when the data is invalid (i.e. invalid data format, * @retval -EBADMSG when the data is invalid (i.e. invalid data format,
* invalid length, ...) * invalid length, ...)
* @retval -EBUSY when the instance is busy. * @retval -EBUSY when the instance is busy.
@ -250,6 +251,7 @@ int ipc_service_send(struct ipc_ept *ept, const void *data, size_t len);
* @retval -EIO when no backend is registered or send hook is missing from * @retval -EIO when no backend is registered or send hook is missing from
* backend. * backend.
* @retval -EINVAL when instance or endpoint is invalid. * @retval -EINVAL when instance or endpoint is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -ENOTSUP when the operation is not supported by backend. * @retval -ENOTSUP when the operation is not supported by backend.
* *
* @retval size TX buffer size on success. * @retval size TX buffer size on success.
@ -294,6 +296,7 @@ int ipc_service_get_tx_buffer_size(struct ipc_ept *ept);
* @retval -EIO when no backend is registered or send hook is missing from * @retval -EIO when no backend is registered or send hook is missing from
* backend. * backend.
* @retval -EINVAL when instance or endpoint is invalid. * @retval -EINVAL when instance or endpoint is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -ENOTSUP when the operation or the timeout is not supported by backend. * @retval -ENOTSUP when the operation or the timeout is not supported by backend.
* @retval -ENOBUFS when there are no TX buffers available. * @retval -ENOBUFS when there are no TX buffers available.
* @retval -EALREADY when a buffer was already claimed and not yet released. * @retval -EALREADY when a buffer was already claimed and not yet released.
@ -316,6 +319,7 @@ int ipc_service_get_tx_buffer(struct ipc_ept *ept, void **data, uint32_t *size,
* @retval -EIO when no backend is registered or send hook is missing from * @retval -EIO when no backend is registered or send hook is missing from
* backend. * backend.
* @retval -EINVAL when instance or endpoint is invalid. * @retval -EINVAL when instance or endpoint is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -ENOTSUP when this is not supported by backend. * @retval -ENOTSUP when this is not supported by backend.
* @retval -EALREADY when the buffer was already dropped. * @retval -EALREADY when the buffer was already dropped.
* @retval -ENXIO when the buffer was not obtained using @ref * @retval -ENXIO when the buffer was not obtained using @ref
@ -350,6 +354,7 @@ int ipc_service_drop_tx_buffer(struct ipc_ept *ept, const void *data);
* @retval -EIO when no backend is registered or send hook is missing from * @retval -EIO when no backend is registered or send hook is missing from
* backend. * backend.
* @retval -EINVAL when instance or endpoint is invalid. * @retval -EINVAL when instance or endpoint is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -EBADMSG when the data is invalid (i.e. invalid data format, * @retval -EBADMSG when the data is invalid (i.e. invalid data format,
* invalid length, ...) * invalid length, ...)
* @retval -EBUSY when the instance is busy. * @retval -EBUSY when the instance is busy.
@ -375,6 +380,7 @@ int ipc_service_send_nocopy(struct ipc_ept *ept, const void *data, size_t len);
* @retval -EIO when no backend is registered or release hook is missing from * @retval -EIO when no backend is registered or release hook is missing from
* backend. * backend.
* @retval -EINVAL when instance or endpoint is invalid. * @retval -EINVAL when instance or endpoint is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -EALREADY when the buffer data has been hold already. * @retval -EALREADY when the buffer data has been hold already.
* @retval -ENOTSUP when this is not supported by backend. * @retval -ENOTSUP when this is not supported by backend.
* *
@ -398,6 +404,7 @@ int ipc_service_hold_rx_buffer(struct ipc_ept *ept, void *data);
* @retval -EIO when no backend is registered or release hook is missing from * @retval -EIO when no backend is registered or release hook is missing from
* backend. * backend.
* @retval -EINVAL when instance or endpoint is invalid. * @retval -EINVAL when instance or endpoint is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -EALREADY when the buffer data has been already released. * @retval -EALREADY when the buffer data has been already released.
* @retval -ENOTSUP when this is not supported by backend. * @retval -ENOTSUP when this is not supported by backend.
* @retval -ENXIO when the buffer was not hold before using @ref * @retval -ENXIO when the buffer was not hold before using @ref

View file

@ -45,6 +45,7 @@ struct ipc_service_backend {
* @param[in] len Number of bytes to send. * @param[in] len Number of bytes to send.
* *
* @retval -EINVAL when instance is invalid. * @retval -EINVAL when instance is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -EBADMSG when the message is invalid. * @retval -EBADMSG when the message is invalid.
* @retval -EBUSY when the instance is busy or not ready. * @retval -EBUSY when the instance is busy or not ready.
* @retval -ENOMEM when no memory / buffers are available. * @retval -ENOMEM when no memory / buffers are available.
@ -79,6 +80,7 @@ struct ipc_service_backend {
* @param[in] token Backend-specific token. * @param[in] token Backend-specific token.
* *
* @retval -EINVAL when instance is invalid. * @retval -EINVAL when instance is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -ENOTSUP when the operation is not supported. * @retval -ENOTSUP when the operation is not supported.
* *
* @retval size TX buffer size on success. * @retval size TX buffer size on success.
@ -96,6 +98,7 @@ struct ipc_service_backend {
* @param[in] wait Timeout waiting for an available TX buffer. * @param[in] wait Timeout waiting for an available TX buffer.
* *
* @retval -EINVAL when instance is invalid. * @retval -EINVAL when instance is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -ENOTSUP when the operation or the timeout is not supported. * @retval -ENOTSUP when the operation or the timeout is not supported.
* @retval -ENOBUFS when there are no TX buffers available. * @retval -ENOBUFS when there are no TX buffers available.
* @retval -EALREADY when a buffer was already claimed and not yet released. * @retval -EALREADY when a buffer was already claimed and not yet released.
@ -116,6 +119,7 @@ struct ipc_service_backend {
* @param[in] data Pointer to the TX buffer. * @param[in] data Pointer to the TX buffer.
* *
* @retval -EINVAL when instance is invalid. * @retval -EINVAL when instance is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -ENOTSUP when this function is not supported. * @retval -ENOTSUP when this function is not supported.
* @retval -EALREADY when the buffer was already dropped. * @retval -EALREADY when the buffer was already dropped.
* *
@ -136,6 +140,7 @@ struct ipc_service_backend {
* @param[in] len Number of bytes to send. * @param[in] len Number of bytes to send.
* *
* @retval -EINVAL when instance is invalid. * @retval -EINVAL when instance is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -EBADMSG when the data is invalid (i.e. invalid data format, * @retval -EBADMSG when the data is invalid (i.e. invalid data format,
* invalid length, ...) * invalid length, ...)
* @retval -EBUSY when the instance is busy or not ready. * @retval -EBUSY when the instance is busy or not ready.
@ -154,6 +159,7 @@ struct ipc_service_backend {
* @param[in] data Pointer to the RX buffer to hold. * @param[in] data Pointer to the RX buffer to hold.
* *
* @retval -EINVAL when instance is invalid. * @retval -EINVAL when instance is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -EALREADY when the buffer data has been already hold. * @retval -EALREADY when the buffer data has been already hold.
* @retval -ENOTSUP when this function is not supported. * @retval -ENOTSUP when this function is not supported.
* *
@ -171,6 +177,7 @@ struct ipc_service_backend {
* @param[in] data Pointer to the RX buffer to release. * @param[in] data Pointer to the RX buffer to release.
* *
* @retval -EINVAL when instance is invalid. * @retval -EINVAL when instance is invalid.
* @retval -ENOENT when the endpoint is not registered with the instance.
* @retval -EALREADY when the buffer data has been already released. * @retval -EALREADY when the buffer data has been already released.
* @retval -ENOTSUP when this function is not supported. * @retval -ENOTSUP when this function is not supported.
* *

View file

@ -413,6 +413,11 @@ static int send(const struct device *instance, void *token,
rpmsg_ept = (struct ipc_rpmsg_ept *) token; rpmsg_ept = (struct ipc_rpmsg_ept *) token;
/* Endpoint is not registered with instance */
if (!rpmsg_ept) {
return -ENOENT;
}
ret = rpmsg_send(&rpmsg_ept->ep, msg, len); ret = rpmsg_send(&rpmsg_ept->ep, msg, len);
/* No buffers available */ /* No buffers available */
@ -441,6 +446,11 @@ static int send_nocopy(const struct device *instance, void *token,
rpmsg_ept = (struct ipc_rpmsg_ept *) token; rpmsg_ept = (struct ipc_rpmsg_ept *) token;
/* Endpoint is not registered with instance */
if (!rpmsg_ept) {
return -ENOENT;
}
return rpmsg_send_nocopy(&rpmsg_ept->ep, msg, len); return rpmsg_send_nocopy(&rpmsg_ept->ep, msg, len);
} }
@ -521,6 +531,11 @@ static int get_tx_buffer(const struct device *instance, void *token,
rpmsg_ept = (struct ipc_rpmsg_ept *) token; rpmsg_ept = (struct ipc_rpmsg_ept *) token;
/* Endpoint is not registered with instance */
if (!rpmsg_ept) {
return -ENOENT;
}
if (!r_data || !size) { if (!r_data || !size) {
return -EINVAL; return -EINVAL;
} }
@ -563,6 +578,11 @@ static int hold_rx_buffer(const struct device *instance, void *token,
rpmsg_ept = (struct ipc_rpmsg_ept *) token; rpmsg_ept = (struct ipc_rpmsg_ept *) token;
/* Endpoint is not registered with instance */
if (!rpmsg_ept) {
return -ENOENT;
}
rpmsg_hold_rx_buffer(&rpmsg_ept->ep, data); rpmsg_hold_rx_buffer(&rpmsg_ept->ep, data);
return 0; return 0;
@ -575,6 +595,11 @@ static int release_rx_buffer(const struct device *instance, void *token,
rpmsg_ept = (struct ipc_rpmsg_ept *) token; rpmsg_ept = (struct ipc_rpmsg_ept *) token;
/* Endpoint is not registered with instance */
if (!rpmsg_ept) {
return -ENOENT;
}
rpmsg_release_rx_buffer(&rpmsg_ept->ep, data); rpmsg_release_rx_buffer(&rpmsg_ept->ep, data);
return 0; return 0;

View file

@ -72,6 +72,11 @@ int ipc_service_send(struct ipc_ept *ept, const void *data, size_t len)
return -EINVAL; return -EINVAL;
} }
if (!ept->instance) {
LOG_ERR("Endpoint not registered\n");
return -ENOENT;
}
backend = ept->instance->api; backend = ept->instance->api;
if (!backend || !backend->send) { if (!backend || !backend->send) {
@ -91,6 +96,11 @@ int ipc_service_get_tx_buffer_size(struct ipc_ept *ept)
return -EINVAL; return -EINVAL;
} }
if (!ept->instance) {
LOG_ERR("Endpoint not registered\n");
return -ENOENT;
}
backend = ept->instance->api; backend = ept->instance->api;
if (!backend) { if (!backend) {
@ -115,6 +125,11 @@ int ipc_service_get_tx_buffer(struct ipc_ept *ept, void **data, uint32_t *len, k
return -EINVAL; return -EINVAL;
} }
if (!ept->instance) {
LOG_ERR("Endpoint not registered\n");
return -ENOENT;
}
backend = ept->instance->api; backend = ept->instance->api;
if (!backend) { if (!backend) {
@ -139,6 +154,11 @@ int ipc_service_drop_tx_buffer(struct ipc_ept *ept, const void *data)
return -EINVAL; return -EINVAL;
} }
if (!ept->instance) {
LOG_ERR("Endpoint not registered\n");
return -ENOENT;
}
backend = ept->instance->api; backend = ept->instance->api;
if (!backend) { if (!backend) {
@ -163,6 +183,11 @@ int ipc_service_send_nocopy(struct ipc_ept *ept, const void *data, size_t len)
return -EINVAL; return -EINVAL;
} }
if (!ept->instance) {
LOG_ERR("Endpoint not registered\n");
return -ENOENT;
}
backend = ept->instance->api; backend = ept->instance->api;
if (!backend) { if (!backend) {
@ -187,6 +212,11 @@ int ipc_service_hold_rx_buffer(struct ipc_ept *ept, void *data)
return -EINVAL; return -EINVAL;
} }
if (!ept->instance) {
LOG_ERR("Endpoint not registered\n");
return -ENOENT;
}
backend = ept->instance->api; backend = ept->instance->api;
if (!backend) { if (!backend) {
@ -211,6 +241,11 @@ int ipc_service_release_rx_buffer(struct ipc_ept *ept, void *data)
return -EINVAL; return -EINVAL;
} }
if (!ept->instance) {
LOG_ERR("Endpoint not registered\n");
return -ENOENT;
}
backend = ept->instance->api; backend = ept->instance->api;
if (!backend) { if (!backend) {