Skip to content

top: fix out-of-band read when using -p with exactly 20 pids

Yoann Lecuyer requested to merge ylecuyer/procps:patch-1 into master

When using top with -p and exactly 20 pids, there is an out-of-band read

ylecuyer@ylecuyer-U32U:~/Projects/procps$ ./top/top -b -n 1 -p 1,338,333,4,336,6,7,8,9,10,11,12,13,14,15,16,339,18,19,20
top - 00:24:51 up  1:34,  1 user,  load average: 0,47, 0,75, 1,13
Tasks:  22 total,   0 running,  22 sleeping,   0 stopped,   0 zombie
%Cpu0  :  13,3/0,0    13[|||||||||||||                                                                                       ]
%Cpu1  :  18,8/6,2    25[|||||||||||||||||||||||||                                                                           ]
GiB Mem : 54,3/3,5      [                                                                                                    ]
GiB Swap:  1,6/2,0      [                                                                                                    ]

  PID USER      PR  NI    VIRT    RES  %CPU  %MEM     TIME+ S COMMAND
    1 root      20   0  156,2m   8,8m   0,0   0,2   0:03.79 S /sbin/init splash
    4 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.00 I [kworker/0:0H]
    6 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.00 I [mm_percpu_wq]
    7 root      20   0    0,0m   0,0m   0,0   0,0   0:02.72 S [ksoftirqd/0]
    8 root      20   0    0,0m   0,0m   0,0   0,0   0:19.12 I [rcu_sched]
    9 root      20   0    0,0m   0,0m   0,0   0,0   0:00.00 I [rcu_bh]
   10 root      rt   0    0,0m   0,0m   0,0   0,0   0:00.22 S [migration/0]
   11 root      rt   0    0,0m   0,0m   0,0   0,0   0:00.04 S [watchdog/0]
   12 root      20   0    0,0m   0,0m   0,0   0,0   0:00.00 S [cpuhp/0]
   13 root      20   0    0,0m   0,0m   0,0   0,0   0:00.00 S [cpuhp/1]
   14 root      rt   0    0,0m   0,0m   0,0   0,0   0:00.04 S [watchdog/1]
   15 root      rt   0    0,0m   0,0m   0,0   0,0   0:00.24 S [migration/1]
   16 root      20   0    0,0m   0,0m   0,0   0,0   0:00.98 S [ksoftirqd/1]
   18 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.00 I [kworker/1:0H]
    2 root      20   0    0,0m   0,0m   0,0   0,0   0:00.02 S [kthreadd]
    2 root      20   0    0,0m   0,0m   0,0   0,0   0:00.02 S  `- [kthreadd]
   19 root      20   0    0,0m   0,0m   0,0   0,0   0:00.01 S      `- [kdevtmpfs]
   20 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.00 I      `- [netns]
  333 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.01 S      `- [loop3]
  336 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.01 S      `- [loop4]
  338 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.01 S      `- [loop5]
  339 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.02 S      `- [loop6]

Here you can see there are 22 tasks

    2 root      20   0    0,0m   0,0m   0,0   0,0   0:00.02 S [kthreadd]
    2 root      20   0    0,0m   0,0m   0,0   0,0   0:00.02 S  `- [kthreadd]

Those 2 tasks shouldn't be here

This happen because when we use the -p option, we fill the Monpids array with the pids. Unused slots are initialized to 0. The PROCTAB finder is the listed_nextpid as we have the PROC_PID flag set

In the case where we have exactly 20 pids, all slots of Monpids are filled and

pid_t tgid = *(PT->pids)++;
if(likely(tgid)){
...
}

Never encounter the end of the array. I have added an extra slot to the array so it ends correclty.

With the fix the output is now correct

ylecuyer@ylecuyer-U32U:~/Projects/procps$ ./top/top -b -n 1 -p 1,338,333,4,336,6,7,8,9,10,11,12,13,14,15,16,339,18,19,20
top - 00:26:38 up  1:35,  1 user,  load average: 0,26, 0,60, 1,03
Tasks:  20 total,   0 running,  20 sleeping,   0 stopped,   0 zombie
%Cpu0  :   0,0/0,0     0[                                                                                                    ]
%Cpu1  :   0,0/6,2     6[||||||                                                                                              ]
GiB Mem : 54,2/3,5      [                                                                                                    ]
GiB Swap:  1,6/2,0      [                                                                                                    ]

  PID USER      PR  NI    VIRT    RES  %CPU  %MEM     TIME+ S COMMAND
    1 root      20   0  156,2m   8,8m   0,0   0,2   0:03.79 S /sbin/init splash
    4 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.00 I [kworker/0:0H]
    6 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.00 I [mm_percpu_wq]
    7 root      20   0    0,0m   0,0m   0,0   0,0   0:02.73 S [ksoftirqd/0]
    8 root      20   0    0,0m   0,0m   0,0   0,0   0:19.37 I [rcu_sched]
    9 root      20   0    0,0m   0,0m   0,0   0,0   0:00.00 I [rcu_bh]
   10 root      rt   0    0,0m   0,0m   0,0   0,0   0:00.22 S [migration/0]
   11 root      rt   0    0,0m   0,0m   0,0   0,0   0:00.04 S [watchdog/0]
   12 root      20   0    0,0m   0,0m   0,0   0,0   0:00.00 S [cpuhp/0]
   13 root      20   0    0,0m   0,0m   0,0   0,0   0:00.00 S [cpuhp/1]
   14 root      rt   0    0,0m   0,0m   0,0   0,0   0:00.04 S [watchdog/1]
   15 root      rt   0    0,0m   0,0m   0,0   0,0   0:00.24 S [migration/1]
   16 root      20   0    0,0m   0,0m   0,0   0,0   0:00.98 S [ksoftirqd/1]
   18 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.00 I [kworker/1:0H]
   19 root      20   0    0,0m   0,0m   0,0   0,0   0:00.01 S [kdevtmpfs]
   20 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.00 I [netns]
  333 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.01 S [loop3]
  336 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.01 S [loop4]
  338 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.01 S [loop5]
  339 root       0 -20    0,0m   0,0m   0,0   0,0   0:00.02 S [loop6]

Merge request reports