perf maps: Add maps__refcnt() accessor to allow checking maps pointer
authorArnaldo Carvalho de Melo <acme@redhat.com>
Tue, 18 Apr 2023 20:33:48 +0000 (17:33 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 19 Apr 2023 13:52:54 +0000 (10:52 -0300)
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>
tools/perf/tests/thread-maps-share.c
tools/perf/util/maps.c
tools/perf/util/maps.h

index 84edd82..caf8fbe 100644 (file)
@@ -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);
 
index 5afed53..953dc20 100644 (file)
 
 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);
 }
 
index bde3390..cfb1b79 100644 (file)
@@ -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)
 {