diff options
author | Ian Rogers <irogers@google.com> | 2023-04-19 12:57:53 -0300 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2023-04-19 12:57:53 -0300 |
commit | 2832ef81d4c75d4f0e3945bd2cb0b7012313cbb3 (patch) | |
tree | f52c0d327cc431927e5df4880295060ab462466f /tools/perf/util/map.h | |
parent | e6a9efcee55f084a5450e4853ecbbaa0b086dcd0 (diff) |
perf map: Add reference count checking
There's no strict get/put policy with map that leads to leaks or use
after free. Reference count checking identifies correct pairing of gets
and puts.
Committer notes:
Extracted from a larger patch removing bits that were covered by the use
of pre-existing map__ accessors (e.g. maps__nr_maps()) and new ones
added (map__refcnt() and the maps__set_ ones) to reduce
RC_CHK_ACCESS(maps)-> source code pollution.
Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexey Bayduraev <alexey.v.bayduraev@linux.intel.com>
Cc: Dmitriy Vyukov <dvyukov@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Riccardo Mancini <rickyman7@gmail.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Stephen Brennan <stephen.s.brennan@oracle.com>
Link: https://lore.kernel.org/lkml/20230407230405.2931830-6-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/map.h')
-rw-r--r-- | tools/perf/util/map.h | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 0760c671314d..823ab7fc0acf 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -10,12 +10,13 @@ #include <string.h> #include <stdbool.h> #include <linux/types.h> +#include <internal/rc_check.h> struct dso; struct maps; struct machine; -struct map { +DECLARE_RC_STRUCT(map) { u64 start; u64 end; bool erange_warned:1; @@ -49,72 +50,72 @@ u64 identity__map_ip(const struct map *map __maybe_unused, u64 ip); static inline struct dso *map__dso(const struct map *map) { - return map->dso; + return RC_CHK_ACCESS(map)->dso; } static inline u64 map__map_ip(const struct map *map, u64 ip) { - return map->map_ip(map, ip); + return RC_CHK_ACCESS(map)->map_ip(map, ip); } static inline u64 map__unmap_ip(const struct map *map, u64 ip) { - return map->unmap_ip(map, ip); + return RC_CHK_ACCESS(map)->unmap_ip(map, ip); } static inline void *map__map_ip_ptr(struct map *map) { - return map->map_ip; + return RC_CHK_ACCESS(map)->map_ip; } static inline void* map__unmap_ip_ptr(struct map *map) { - return map->unmap_ip; + return RC_CHK_ACCESS(map)->unmap_ip; } static inline u64 map__start(const struct map *map) { - return map->start; + return RC_CHK_ACCESS(map)->start; } static inline u64 map__end(const struct map *map) { - return map->end; + return RC_CHK_ACCESS(map)->end; } static inline u64 map__pgoff(const struct map *map) { - return map->pgoff; + return RC_CHK_ACCESS(map)->pgoff; } static inline u64 map__reloc(const struct map *map) { - return map->reloc; + return RC_CHK_ACCESS(map)->reloc; } static inline u32 map__flags(const struct map *map) { - return map->flags; + return RC_CHK_ACCESS(map)->flags; } static inline u32 map__prot(const struct map *map) { - return map->prot; + return RC_CHK_ACCESS(map)->prot; } static inline bool map__priv(const struct map *map) { - return map->priv; + return RC_CHK_ACCESS(map)->priv; } static inline refcount_t *map__refcnt(struct map *map) { - return &map->refcnt; + return &RC_CHK_ACCESS(map)->refcnt; } static inline bool map__erange_warned(struct map *map) { - return map->erange_warned; + return RC_CHK_ACCESS(map)->erange_warned; } static inline size_t map__size(const struct map *map) @@ -173,9 +174,12 @@ struct map *map__clone(struct map *map); static inline struct map *map__get(struct map *map) { - if (map) + struct map *result; + + if (RC_CHK_GET(result, map)) refcount_inc(map__refcnt(map)); - return map; + + return result; } void map__put(struct map *map); @@ -249,51 +253,51 @@ static inline int is_no_dso_memory(const char *filename) static inline void map__set_start(struct map *map, u64 start) { - map->start = start; + RC_CHK_ACCESS(map)->start = start; } static inline void map__set_end(struct map *map, u64 end) { - map->end = end; + RC_CHK_ACCESS(map)->end = end; } static inline void map__set_pgoff(struct map *map, u64 pgoff) { - map->pgoff = pgoff; + RC_CHK_ACCESS(map)->pgoff = pgoff; } static inline void map__add_pgoff(struct map *map, u64 inc) { - map->pgoff += inc; + RC_CHK_ACCESS(map)->pgoff += inc; } static inline void map__set_reloc(struct map *map, u64 reloc) { - map->reloc = reloc; + RC_CHK_ACCESS(map)->reloc = reloc; } static inline void map__set_priv(struct map *map, int priv) { - map->priv = priv; + RC_CHK_ACCESS(map)->priv = priv; } static inline void map__set_erange_warned(struct map *map, bool erange_warned) { - map->erange_warned = erange_warned; + RC_CHK_ACCESS(map)->erange_warned = erange_warned; } static inline void map__set_dso(struct map *map, struct dso *dso) { - map->dso = dso; + RC_CHK_ACCESS(map)->dso = dso; } static inline void map__set_map_ip(struct map *map, u64 (*map_ip)(const struct map *map, u64 ip)) { - map->map_ip = map_ip; + RC_CHK_ACCESS(map)->map_ip = map_ip; } static inline void map__set_unmap_ip(struct map *map, u64 (*unmap_ip)(const struct map *map, u64 rip)) { - map->unmap_ip = unmap_ip; + RC_CHK_ACCESS(map)->unmap_ip = unmap_ip; } #endif /* __PERF_MAP_H */ |