Do not sort the task scan result from /proc when synthesizing perf events
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
linux (Ubuntu) |
In Progress
|
Undecided
|
Chengen Du | ||
Jammy |
Fix Released
|
Medium
|
Chengen Du |
Bug Description
[Impact]
The perf tool use scandir() to iterate threads and sort in alphabetical order when synthesizing PERF_RECORD_ events.
If the process ID is 9999 and it has one thread (tid = 10000), the thread will be processed before the process.
It results in PERF_RECORD_FORK events that come before PERF_RECORD_MMAP2 events.
The callstack will have missing symbols for threads where `PERF_RECORD_FORK` events are processed before the `PERF_RECORD_MMAP2` event for the corresponding process.
[Fix]
Do not use alphasort when calling scandir()
363afa3aef24f5e
[Test Plan]
<test.lua>
function update_last_pid()
local file <close> = io.open(
file:write(9997)
end
update_last_pid()
os.execute(
<reproducer.cpp>
#include <iostream>
#include <thread>
#include <unistd.h>
constexpr int kThreadNum = 10;
void thread_job() { sleep(30); }
int main(void) {
std::thread threads[
std::cout << "Parent process with pid " << getpid() << std::endl;
for (int i = 0; i < kThreadNum; ++i) {
threads[i] = std::thread(
}
for (int i = 0; i < kThreadNum; ++i) {
threads[
}
std::cout << "All threads have finished" << std::endl;
return 0;
}
The flow is to set /proc/sys/
The script (test.lua) sets ns_last_pid to 9997 and executes the reproducer (reproducer.cpp).
After the reproducer creates ten threads, we execute the perf command as follows: perf record -F 49 -e cpu-clock -a -g sleep 20.
Here is the result of command: perf report -f --tasks --mmaps -D | egrep -i 'perf_record_
Before applying the patch, the output of the perf command was as follows:
0 0 0x34910 [0x40]: PERF_RECORD_
0 0 0x34990 [0x40]: PERF_RECORD_
0 0 0x34a10 [0x40]: PERF_RECORD_
0 0 0x34a90 [0x40]: PERF_RECORD_
0 0 0x34b10 [0x40]: PERF_RECORD_
0 0 0x34b90 [0x40]: PERF_RECORD_
0 0 0x34c10 [0x40]: PERF_RECORD_
0 0 0x34c90 [0x40]: PERF_RECORD_
0 0 0x34d10 [0x40]: PERF_RECORD_
0 0 0x34d90 [0x40]: PERF_RECORD_
0 0 0x34e10 [0x40]: PERF_RECORD_
0 0 0x34e90 [0x80]: PERF_RECORD_MMAP2 9999/9999: [0x555de0159000
0 0 0x34f10 [0x90]: PERF_RECORD_MMAP2 9999/9999: [0x7f9cd17f8000
0 0 0x34fa0 [0x90]: PERF_RECORD_MMAP2 9999/9999: [0x7f9cd18f9000
0 0 0x35030 [0x90]: PERF_RECORD_MMAP2 9999/9999: [0x7f9cd1afc000
0 0 0x350c0 [0x98]: PERF_RECORD_MMAP2 9999/9999: [0x7f9cd1bb3000
0 0 0x35158 [0x98]: PERF_RECORD_MMAP2 9999/9999: [0x7f9cd1d4e000
0 0 0x351f0 [0x70]: PERF_RECORD_MMAP2 9999/9999: [0x7ffc983bb000
0 0 0x35260 [0x78]: PERF_RECORD_MMAP2 9999/9999: [0xffffffffff60
After applying the patch, the output of the perf command is as follows:
0 0 0x30c28 [0x40]: PERF_RECORD_
0 0 0x30ca8 [0x80]: PERF_RECORD_MMAP2 9999/9999: [0x5642c7635000
0 0 0x30d28 [0x90]: PERF_RECORD_MMAP2 9999/9999: [0x7f8ada03d000
0 0 0x30db8 [0x90]: PERF_RECORD_MMAP2 9999/9999: [0x7f8ada13e000
0 0 0x30e48 [0x90]: PERF_RECORD_MMAP2 9999/9999: [0x7f8ada341000
0 0 0x30ed8 [0x98]: PERF_RECORD_MMAP2 9999/9999: [0x7f8ada3f8000
0 0 0x30f70 [0x98]: PERF_RECORD_MMAP2 9999/9999: [0x7f8ada593000
0 0 0x31008 [0x70]: PERF_RECORD_MMAP2 9999/9999: [0x7ffcb2116000
0 0 0x31078 [0x78]: PERF_RECORD_MMAP2 9999/9999: [0xffffffffff60
0 0 0x310f0 [0x40]: PERF_RECORD_
0 0 0x31170 [0x40]: PERF_RECORD_
0 0 0x311f0 [0x40]: PERF_RECORD_
0 0 0x31270 [0x40]: PERF_RECORD_
0 0 0x312f0 [0x40]: PERF_RECORD_
0 0 0x31370 [0x40]: PERF_RECORD_
0 0 0x313f0 [0x40]: PERF_RECORD_
0 0 0x31470 [0x40]: PERF_RECORD_
0 0 0x314f0 [0x40]: PERF_RECORD_
0 0 0x31570 [0x40]: PERF_RECORD_
[Where problems could occur]
The fix will apply upstream commits, so the regression can be considered as low.
CVE References
Changed in linux (Ubuntu): | |
assignee: | nobody → ChengEn, Du (chengendu) |
Changed in linux (Ubuntu Jammy): | |
assignee: | nobody → ChengEn, Du (chengendu) |
Changed in linux (Ubuntu): | |
status: | Incomplete → In Progress |
Changed in linux (Ubuntu Jammy): | |
status: | New → In Progress |
Changed in linux (Ubuntu Jammy): | |
importance: | Undecided → Medium |
status: | In Progress → Fix Committed |
tags: |
added: verification-done-jammy removed: verification-needed-jammy |
tags: |
added: verification-done-focal removed: verification-needed-focal |
tags: |
added: verification-done-jammy removed: verification-needed-jammy |
This bug is missing log files that will aid in diagnosing the problem. While running an Ubuntu kernel (not a mainline or third-party kernel) please enter the following command in a terminal window:
apport-collect 2008971
and then change the status of the bug to 'Confirmed'.
If, due to the nature of the issue you have encountered, you are unable to run this command, please add a comment stating that fact and change the bug status to 'Confirmed'.
This change has been made by an automated script, maintained by the Ubuntu Kernel Team.