Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf evlist: Convert perf_map.refcnt from atomic_t to refcount_t

The refcount_t type and corresponding API should be used instead of
atomic_t when the variable is used as a reference counter.

This allows to avoid accidental refcounter overflows that might lead to
use-after-free situations.

Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: David Windsor <dwindsor@gmail.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Kook <keescook@chromium.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: David Windsor <dwindsor@gmail.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Hans Liljestrand <ishkamiel@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kees Kook <keescook@chromium.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Matija Glavinic Pecotic <matija.glavinic-pecotic.ext@nokia.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: alsa-devel@alsa-project.org
Link: http://lkml.kernel.org/r/1487691303-31858-8-git-send-email-elena.reshetova@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Elena Reshetova and committed by
Arnaldo Carvalho de Melo
25a3720c ead05e8f

+11 -11
+9 -9
tools/perf/util/evlist.c
··· 777 777 /* 778 778 * Check if event was unmapped due to a POLLHUP/POLLERR. 779 779 */ 780 - if (!atomic_read(&md->refcnt)) 780 + if (!refcount_read(&md->refcnt)) 781 781 return NULL; 782 782 783 783 head = perf_mmap__read_head(md); ··· 794 794 /* 795 795 * Check if event was unmapped due to a POLLHUP/POLLERR. 796 796 */ 797 - if (!atomic_read(&md->refcnt)) 797 + if (!refcount_read(&md->refcnt)) 798 798 return NULL; 799 799 800 800 head = perf_mmap__read_head(md); ··· 856 856 { 857 857 u64 head; 858 858 859 - if (!atomic_read(&md->refcnt)) 859 + if (!refcount_read(&md->refcnt)) 860 860 return; 861 861 862 862 head = perf_mmap__read_head(md); ··· 875 875 876 876 static void perf_mmap__get(struct perf_mmap *map) 877 877 { 878 - atomic_inc(&map->refcnt); 878 + refcount_inc(&map->refcnt); 879 879 } 880 880 881 881 static void perf_mmap__put(struct perf_mmap *md) 882 882 { 883 - BUG_ON(md->base && atomic_read(&md->refcnt) == 0); 883 + BUG_ON(md->base && refcount_read(&md->refcnt) == 0); 884 884 885 - if (atomic_dec_and_test(&md->refcnt)) 885 + if (refcount_dec_and_test(&md->refcnt)) 886 886 perf_mmap__munmap(md); 887 887 } 888 888 ··· 894 894 perf_mmap__write_tail(md, old); 895 895 } 896 896 897 - if (atomic_read(&md->refcnt) == 1 && perf_mmap__empty(md)) 897 + if (refcount_read(&md->refcnt) == 1 && perf_mmap__empty(md)) 898 898 perf_mmap__put(md); 899 899 } 900 900 ··· 937 937 munmap(map->base, perf_mmap__mmap_len(map)); 938 938 map->base = NULL; 939 939 map->fd = -1; 940 - atomic_set(&map->refcnt, 0); 940 + refcount_set(&map->refcnt, 0); 941 941 } 942 942 auxtrace_mmap__munmap(&map->auxtrace_mmap); 943 943 } ··· 1001 1001 * evlist layer can't just drop it when filtering events in 1002 1002 * perf_evlist__filter_pollfd(). 1003 1003 */ 1004 - atomic_set(&map->refcnt, 2); 1004 + refcount_set(&map->refcnt, 2); 1005 1005 map->prev = 0; 1006 1006 map->mask = mp->mask; 1007 1007 map->base = mmap(NULL, perf_mmap__mmap_len(map), mp->prot,
+2 -2
tools/perf/util/evlist.h
··· 1 1 #ifndef __PERF_EVLIST_H 2 2 #define __PERF_EVLIST_H 1 3 3 4 - #include <linux/atomic.h> 4 + #include <linux/refcount.h> 5 5 #include <linux/list.h> 6 6 #include <api/fd/array.h> 7 7 #include <stdio.h> ··· 29 29 void *base; 30 30 int mask; 31 31 int fd; 32 - atomic_t refcnt; 32 + refcount_t refcnt; 33 33 u64 prev; 34 34 struct auxtrace_mmap auxtrace_mmap; 35 35 char event_copy[PERF_SAMPLE_MAX_SIZE] __attribute__((aligned(8)));