diff options
author | Steve Schrock <steve.schrock@getcruise.com> | 2024-04-19 16:44:55 +0000 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2024-04-22 11:16:26 -0500 |
commit | e13fb8f498cc9665cf1c077eb61872f2119c71c3 (patch) | |
tree | b39b6322fb4b1754085132e6666748a390148fec | |
parent | 28d60206ba2d17f3149f39638dc7a9e232e848c4 (diff) | |
download | ofono-e13fb8f498cc9665cf1c077eb61872f2119c71c3.tar.gz |
qmi: Prevent clients from unregistering for others
qmi_service_unregister was removing the registration that matched an
integer ID. This would allow a client to unregister a different
client's notification. While this is unlikely it could lead to very
confusing bugs. This is easy to prevent by checking both the ID and
the service handle.
-rw-r--r-- | drivers/qmimodem/qmi.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/qmimodem/qmi.c b/drivers/qmimodem/qmi.c index f406d01a8..5032233ec 100644 --- a/drivers/qmimodem/qmi.c +++ b/drivers/qmimodem/qmi.c @@ -330,12 +330,18 @@ static void __notify_free(void *data) l_free(notify); } +struct notify_compare_details { + uint16_t id; + unsigned int service_handle; +}; + static bool __notify_compare(const void *data, const void *user_data) { const struct qmi_notify *notify = data; - uint16_t id = L_PTR_TO_UINT(user_data); + const struct notify_compare_details *details = user_data; - return notify->id == id; + return notify->id == details->id && + notify->service_handle == details->service_handle; } struct service_find_by_type_data { @@ -2962,16 +2968,17 @@ uint16_t qmi_service_register(struct qmi_service *service, bool qmi_service_unregister(struct qmi_service *service, uint16_t id) { - struct service_family *family; struct qmi_notify *notify; + struct notify_compare_details details; if (!service || !id) return false; - family = service->family; + details.id = id; + details.service_handle = service->handle; - notify = l_queue_remove_if(family->notify_list, __notify_compare, - L_UINT_TO_PTR(id)); + notify = l_queue_remove_if(service->family->notify_list, + __notify_compare, &details); if (!notify) return false; |