aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Schrock <steve.schrock@getcruise.com>2024-04-19 16:44:55 +0000
committerDenis Kenzior <denkenz@gmail.com>2024-04-22 11:16:26 -0500
commite13fb8f498cc9665cf1c077eb61872f2119c71c3 (patch)
treeb39b6322fb4b1754085132e6666748a390148fec
parent28d60206ba2d17f3149f39638dc7a9e232e848c4 (diff)
downloadofono-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.c19
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;