https://gitlab.freedesktop.org/pipewire/pipewire/-/commit/5dfc3494dc4635918e74b9f3d717a39a74b28554.patch https://gitlab.freedesktop.org/pipewire/pipewire/-/commit/c07f0ccb71a9d95944ce3e4d7e453cb50a26b0a2.patch From 5dfc3494dc4635918e74b9f3d717a39a74b28554 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 25 Oct 2021 16:15:17 +0200 Subject: [PATCH] map: use uintptr_t for the next pointer This aligns the low bits of the next field with the low bits of the pointer on big endian cpus. Fixes #1747 --- src/pipewire/map.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pipewire/map.h b/src/pipewire/map.h index f47dfa6b3..1867fa4d3 100644 --- a/src/pipewire/map.h +++ b/src/pipewire/map.h @@ -74,7 +74,7 @@ extern "C" { * first item to get re-used on the next insert. */ union pw_map_item { - uint32_t next; /* next free index */ + uintptr_t next; /* next free index */ void *data; /* data of this item, must be an even address */ }; -- GitLab From c07f0ccb71a9d95944ce3e4d7e453cb50a26b0a2 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 25 Oct 2021 16:11:56 +0200 Subject: [PATCH] map: make _insert_at() fail on a removed item You are only supposed to use _insert_new()/_remove() or _insert_at() on the map, If we detect a _insert_at() to a removed item, return an error because else we might corrupt the free list. Update unit test accordingly. --- src/pipewire/map.h | 15 ++------------- test/test-map.c | 17 +---------------- 2 files changed, 3 insertions(+), 29 deletions(-) diff --git a/src/pipewire/map.h b/src/pipewire/map.h index fd57f7f7c..f47dfa6b3 100644 --- a/src/pipewire/map.h +++ b/src/pipewire/map.h @@ -182,20 +182,9 @@ static inline int pw_map_insert_at(struct pw_map *map, uint32_t id, void *data) if (item == NULL) return -errno; } else { - if (pw_map_id_is_free(map, id)) { - uint32_t *current = &map->free_list; - while (*current != SPA_ID_INVALID) { - uint32_t current_id = (*current) >> 1; - uint32_t *next = &pw_map_get_item(map, current_id)->next; - - if (current_id == id) { - *current = *next; - break; - } - current = next; - } - } item = pw_map_get_item(map, id); + if (pw_map_item_is_free(item)) + return -EINVAL; } item->data = data; return 0; diff --git a/test/test-map.c b/test/test-map.c index dd1df77a8..b6d7681ce 100644 --- a/test/test-map.c +++ b/test/test-map.c @@ -188,7 +188,6 @@ PWTEST(map_insert_at_free) int data[3] = {1, 2, 3}; int new_data = 4; int *ptr[3] = {&data[0], &data[1], &data[3]}; - int *new_ptr = &new_data; int idx[3]; int rc; @@ -225,21 +224,7 @@ PWTEST(map_insert_at_free) } rc = pw_map_insert_at(&map, item_idx, &new_data); - pwtest_neg_errno_ok(rc); - pwtest_ptr_eq(new_ptr, pw_map_lookup(&map, item_idx)); - - if (before_idx != SKIP && before_idx != item_idx) { - rc = pw_map_insert_at(&map, before_idx, &ptr[before_idx]); - pwtest_neg_errno_ok(rc); - pwtest_ptr_eq(&ptr[before_idx], pw_map_lookup(&map, before_idx)); - } - - if (after_idx != SKIP && after_idx != item_idx) { - rc = pw_map_insert_at(&map, after_idx, &ptr[after_idx]); - pwtest_neg_errno_ok(rc); - pwtest_ptr_eq(&ptr[after_idx], pw_map_lookup(&map, after_idx)); - } - + pwtest_neg_errno(rc, -EINVAL); pw_map_clear(&map); return PWTEST_PASS; -- GitLab