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

perf thread_map: Convert thread_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-10-git-send-email-elena.reshetova@intel.com
[ Did missing tests/thread-map.c conversion ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Elena Reshetova and committed by
Arnaldo Carvalho de Melo
364fed35 e34f5b11

+15 -15
+3 -3
tools/perf/tests/thread-map.c
··· 29 29 thread_map__comm(map, 0) && 30 30 !strcmp(thread_map__comm(map, 0), NAME)); 31 31 TEST_ASSERT_VAL("wrong refcnt", 32 - atomic_read(&map->refcnt) == 1); 32 + refcount_read(&map->refcnt) == 1); 33 33 thread_map__put(map); 34 34 35 35 /* test dummy pid */ ··· 44 44 thread_map__comm(map, 0) && 45 45 !strcmp(thread_map__comm(map, 0), "dummy")); 46 46 TEST_ASSERT_VAL("wrong refcnt", 47 - atomic_read(&map->refcnt) == 1); 47 + refcount_read(&map->refcnt) == 1); 48 48 thread_map__put(map); 49 49 return 0; 50 50 } ··· 71 71 thread_map__comm(threads, 0) && 72 72 !strcmp(thread_map__comm(threads, 0), NAME)); 73 73 TEST_ASSERT_VAL("wrong refcnt", 74 - atomic_read(&threads->refcnt) == 1); 74 + refcount_read(&threads->refcnt) == 1); 75 75 thread_map__put(threads); 76 76 return 0; 77 77 }
+10 -10
tools/perf/util/thread_map.c
··· 66 66 for (i = 0; i < items; i++) 67 67 thread_map__set_pid(threads, i, atoi(namelist[i]->d_name)); 68 68 threads->nr = items; 69 - atomic_set(&threads->refcnt, 1); 69 + refcount_set(&threads->refcnt, 1); 70 70 } 71 71 72 72 for (i=0; i<items; i++) ··· 83 83 if (threads != NULL) { 84 84 thread_map__set_pid(threads, 0, tid); 85 85 threads->nr = 1; 86 - atomic_set(&threads->refcnt, 1); 86 + refcount_set(&threads->refcnt, 1); 87 87 } 88 88 89 89 return threads; ··· 105 105 goto out_free_threads; 106 106 107 107 threads->nr = 0; 108 - atomic_set(&threads->refcnt, 1); 108 + refcount_set(&threads->refcnt, 1); 109 109 110 110 while ((dirent = readdir(proc)) != NULL) { 111 111 char *end; ··· 235 235 out: 236 236 strlist__delete(slist); 237 237 if (threads) 238 - atomic_set(&threads->refcnt, 1); 238 + refcount_set(&threads->refcnt, 1); 239 239 return threads; 240 240 241 241 out_free_namelist: ··· 255 255 if (threads != NULL) { 256 256 thread_map__set_pid(threads, 0, -1); 257 257 threads->nr = 1; 258 - atomic_set(&threads->refcnt, 1); 258 + refcount_set(&threads->refcnt, 1); 259 259 } 260 260 return threads; 261 261 } ··· 300 300 } 301 301 out: 302 302 if (threads) 303 - atomic_set(&threads->refcnt, 1); 303 + refcount_set(&threads->refcnt, 1); 304 304 return threads; 305 305 306 306 out_free_threads: ··· 326 326 if (threads) { 327 327 int i; 328 328 329 - WARN_ONCE(atomic_read(&threads->refcnt) != 0, 329 + WARN_ONCE(refcount_read(&threads->refcnt) != 0, 330 330 "thread map refcnt unbalanced\n"); 331 331 for (i = 0; i < threads->nr; i++) 332 332 free(thread_map__comm(threads, i)); ··· 337 337 struct thread_map *thread_map__get(struct thread_map *map) 338 338 { 339 339 if (map) 340 - atomic_inc(&map->refcnt); 340 + refcount_inc(&map->refcnt); 341 341 return map; 342 342 } 343 343 344 344 void thread_map__put(struct thread_map *map) 345 345 { 346 - if (map && atomic_dec_and_test(&map->refcnt)) 346 + if (map && refcount_dec_and_test(&map->refcnt)) 347 347 thread_map__delete(map); 348 348 } 349 349 ··· 423 423 threads->map[i].comm = strndup(event->entries[i].comm, 16); 424 424 } 425 425 426 - atomic_set(&threads->refcnt, 1); 426 + refcount_set(&threads->refcnt, 1); 427 427 } 428 428 429 429 struct thread_map *thread_map__new_event(struct thread_map_event *event)
+2 -2
tools/perf/util/thread_map.h
··· 3 3 4 4 #include <sys/types.h> 5 5 #include <stdio.h> 6 - #include <linux/atomic.h> 6 + #include <linux/refcount.h> 7 7 8 8 struct thread_map_data { 9 9 pid_t pid; ··· 11 11 }; 12 12 13 13 struct thread_map { 14 - atomic_t refcnt; 14 + refcount_t refcnt; 15 15 int nr; 16 16 struct thread_map_data map[]; 17 17 };