summaryrefslogtreecommitdiff
path: root/tools/perf
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2023-04-18 17:33:48 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2023-04-19 10:52:54 -0300
commitfe693d951e3c303b4fb6c712f8affecbe9e8b001 (patch)
tree8e38165abc611742b25d7a1f2bfed3406c361193 /tools/perf
parent3ad1be6faef9a482c3098928220fcafaa51a1283 (diff)
perf maps: Add maps__refcnt() accessor to allow checking maps pointer
To remove one more direct access to 'struct maps' so that we can intercept accesses to its instantiations and refcount check it to catch use after free, etc. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/tests/thread-maps-share.c12
-rw-r--r--tools/perf/util/maps.c6
-rw-r--r--tools/perf/util/maps.h5
3 files changed, 14 insertions, 9 deletions
diff --git a/tools/perf/tests/thread-maps-share.c b/tools/perf/tests/thread-maps-share.c
index 84edd82c519e..caf8fbe7c440 100644
--- a/tools/perf/tests/thread-maps-share.c
+++ b/tools/perf/tests/thread-maps-share.c
@@ -43,7 +43,7 @@ static int test__thread_maps_share(struct test_suite *test __maybe_unused, int s
leader && t1 && t2 && t3 && other);
maps = leader->maps;
- TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 4);
+ TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 4);
/* test the maps pointer is shared */
TEST_ASSERT_VAL("maps don't match", maps == t1->maps);
@@ -71,25 +71,25 @@ static int test__thread_maps_share(struct test_suite *test __maybe_unused, int s
machine__remove_thread(machine, other_leader);
other_maps = other->maps;
- TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 2);
+ TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(other_maps)), 2);
TEST_ASSERT_VAL("maps don't match", other_maps == other_leader->maps);
/* release thread group */
thread__put(leader);
- TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 3);
+ TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 3);
thread__put(t1);
- TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 2);
+ TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 2);
thread__put(t2);
- TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&maps->refcnt), 1);
+ TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(maps)), 1);
thread__put(t3);
/* release other group */
thread__put(other_leader);
- TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(&other_maps->refcnt), 1);
+ TEST_ASSERT_EQUAL("wrong refcnt", refcount_read(maps__refcnt(other_maps)), 1);
thread__put(other);
diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c
index 5afed53ea0b4..953dc20d55d7 100644
--- a/tools/perf/util/maps.c
+++ b/tools/perf/util/maps.c
@@ -12,13 +12,13 @@
static void maps__init(struct maps *maps, struct machine *machine)
{
+ refcount_set(maps__refcnt(maps), 1);
maps->entries = RB_ROOT;
init_rwsem(maps__lock(maps));
maps->machine = machine;
maps->last_search_by_name = NULL;
maps->nr_maps = 0;
maps->maps_by_name = NULL;
- refcount_set(&maps->refcnt, 1);
}
static void __maps__free_maps_by_name(struct maps *maps)
@@ -180,14 +180,14 @@ void maps__delete(struct maps *maps)
struct maps *maps__get(struct maps *maps)
{
if (maps)
- refcount_inc(&maps->refcnt);
+ refcount_inc(maps__refcnt(maps));
return maps;
}
void maps__put(struct maps *maps)
{
- if (maps && refcount_dec_and_test(&maps->refcnt))
+ if (maps && refcount_dec_and_test(maps__refcnt(maps)))
maps__delete(maps);
}
diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h
index bde3390c7096..cfb1b79d1671 100644
--- a/tools/perf/util/maps.h
+++ b/tools/perf/util/maps.h
@@ -88,6 +88,11 @@ static inline unsigned int maps__nr_maps(const struct maps *maps)
return maps->nr_maps;
}
+static inline refcount_t *maps__refcnt(struct maps *maps)
+{
+ return &maps->refcnt;
+}
+
#ifdef HAVE_LIBUNWIND_SUPPORT
static inline void *maps__addr_space(struct maps *maps)
{