Patch "libperf evlist: Avoid out-of-bounds access" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    libperf evlist: Avoid out-of-bounds access

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     libperf-evlist-avoid-out-of-bounds-access.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit ec62be8887a9d4f8c112bf77922258902d405d38
Author: Ian Rogers <irogers@xxxxxxxxxx>
Date:   Wed Feb 28 23:07:57 2024 -0800

    libperf evlist: Avoid out-of-bounds access
    
    [ Upstream commit 1947b92464c3268381604bbe2ac977a3fd78192f ]
    
    Parallel testing appears to show a race between allocating and setting
    evsel ids. As there is a bounds check on the xyarray it yields a segv
    like:
    
    ```
    AddressSanitizer:DEADLYSIGNAL
    
    =================================================================
    
    ==484408==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000010
    
    ==484408==The signal is caused by a WRITE memory access.
    
    ==484408==Hint: address points to the zero page.
    
        #0 0x55cef5d4eff4 in perf_evlist__id_hash tools/lib/perf/evlist.c:256
        #1 0x55cef5d4f132 in perf_evlist__id_add tools/lib/perf/evlist.c:274
        #2 0x55cef5d4f545 in perf_evlist__id_add_fd tools/lib/perf/evlist.c:315
        #3 0x55cef5a1923f in store_evsel_ids util/evsel.c:3130
        #4 0x55cef5a19400 in evsel__store_ids util/evsel.c:3147
        #5 0x55cef5888204 in __run_perf_stat tools/perf/builtin-stat.c:832
        #6 0x55cef5888c06 in run_perf_stat tools/perf/builtin-stat.c:960
        #7 0x55cef58932db in cmd_stat tools/perf/builtin-stat.c:2878
    ...
    ```
    
    Avoid this crash by early exiting the perf_evlist__id_add_fd and
    perf_evlist__id_add is the access is out-of-bounds.
    
    Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
    Cc: Yang Jihong <yangjihong1@xxxxxxxxxx>
    Signed-off-by: Namhyung Kim <namhyung@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20240229070757.796244-1-irogers@xxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c
index 5146ff0fa078c..6aa1c35273a18 100644
--- a/tools/lib/perf/evlist.c
+++ b/tools/lib/perf/evlist.c
@@ -224,10 +224,10 @@ u64 perf_evlist__read_format(struct perf_evlist *evlist)
 
 static void perf_evlist__id_hash(struct perf_evlist *evlist,
 				 struct perf_evsel *evsel,
-				 int cpu, int thread, u64 id)
+				 int cpu_map_idx, int thread, u64 id)
 {
 	int hash;
-	struct perf_sample_id *sid = SID(evsel, cpu, thread);
+	struct perf_sample_id *sid = SID(evsel, cpu_map_idx, thread);
 
 	sid->id = id;
 	sid->evsel = evsel;
@@ -245,21 +245,27 @@ void perf_evlist__reset_id_hash(struct perf_evlist *evlist)
 
 void perf_evlist__id_add(struct perf_evlist *evlist,
 			 struct perf_evsel *evsel,
-			 int cpu, int thread, u64 id)
+			 int cpu_map_idx, int thread, u64 id)
 {
-	perf_evlist__id_hash(evlist, evsel, cpu, thread, id);
+	if (!SID(evsel, cpu_map_idx, thread))
+		return;
+
+	perf_evlist__id_hash(evlist, evsel, cpu_map_idx, thread, id);
 	evsel->id[evsel->ids++] = id;
 }
 
 int perf_evlist__id_add_fd(struct perf_evlist *evlist,
 			   struct perf_evsel *evsel,
-			   int cpu, int thread, int fd)
+			   int cpu_map_idx, int thread, int fd)
 {
 	u64 read_data[4] = { 0, };
 	int id_idx = 1; /* The first entry is the counter value */
 	u64 id;
 	int ret;
 
+	if (!SID(evsel, cpu_map_idx, thread))
+		return -1;
+
 	ret = ioctl(fd, PERF_EVENT_IOC_ID, &id);
 	if (!ret)
 		goto add;
@@ -288,7 +294,7 @@ int perf_evlist__id_add_fd(struct perf_evlist *evlist,
 	id = read_data[id_idx];
 
 add:
-	perf_evlist__id_add(evlist, evsel, cpu, thread, id);
+	perf_evlist__id_add(evlist, evsel, cpu_map_idx, thread, id);
 	return 0;
 }
 
diff --git a/tools/lib/perf/include/internal/evlist.h b/tools/lib/perf/include/internal/evlist.h
index f366dbad6a88c..49b17b2b3923f 100644
--- a/tools/lib/perf/include/internal/evlist.h
+++ b/tools/lib/perf/include/internal/evlist.h
@@ -119,11 +119,11 @@ u64 perf_evlist__read_format(struct perf_evlist *evlist);
 
 void perf_evlist__id_add(struct perf_evlist *evlist,
 			 struct perf_evsel *evsel,
-			 int cpu, int thread, u64 id);
+			 int cpu_map_idx, int thread, u64 id);
 
 int perf_evlist__id_add_fd(struct perf_evlist *evlist,
 			   struct perf_evsel *evsel,
-			   int cpu, int thread, int fd);
+			   int cpu_map_idx, int thread, int fd);
 
 void perf_evlist__reset_id_hash(struct perf_evlist *evlist);
 




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux