oss-sec mailing list archives

Re: [Linux] /proc/pid/stat parsing bugs


From: Shawn Webb <shawn.webb () hardenedbsd org>
Date: Thu, 22 Dec 2022 07:47:55 -0500

On Wed, Dec 21, 2022 at 02:15:10PM -0500, Shawn Webb wrote:
On Wed, Dec 21, 2022 at 06:13:17PM +0100, Dmitry Vyukov wrote:
Hello,

This is not a single vulnerability, the list of affected software is
large, but it's not a security issue for all of it.

It occurred to me that most of the Linux procfs /proc/pid/stat and
/proc/pid/task/tid/stat parsing code out there is buggy. The fine
contains a set of numbers about the task:
https://man7.org/linux/man-pages/man5/proc.5.html

e.g. $ cat /proc/self/stat
1715376 (cat) R 1544883 1715376 1544883 34819 1715376 4194304 106 0 0
0 0 0 0 0 20 0 1 0 42505561 9207808 237 18446744073709551615
93955355631616 93955355651497 140737444557056 0 0 0 0 0 0 0 0 0 17 36
0 0 0 0 0 93955355667504 93955355669120 93955385581568 140737444559745
140737444559765 140737444559765 140737444564971 0

Most of the code splits it by space and takes an N-th field.
The problem is that the process name "(cat)" can contain spaces (and
brackets). Potentially some important software (containers/sandboxes)
can be tricked into getting wrong data, and I've seen cases close to
stack overflows (buffer for a fixed number of fields is allocated on
stack).

Some examples:
OpenJDK:
https://sourcegraph.com/github.com/openjdk/jdk/-/blob/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c?L133-139
https://sourcegraph.com/github.com/openjdk/jdk8u/-/blob/jdk/src/solaris/native/sun/management/OperatingSystemImpl.c?L223-229

Ansible:
https://sourcegraph.com/github.com/ansible/ansible/-/blob/lib/ansible/modules/yum.py?L507-510

Libuv:
https://sourcegraph.com/github.com/libuv/libuv/-/blob/src/unix/linux.c?L674-701

bdwgc:
https://sourcegraph.com/github.com/mono/linux-packaging-mono/-/blob/external/bdwgc/os_dep.c?L1138-1155

But really most of the code that does it:
https://sourcegraph.com/search?q=context:global+/%5C%22%5C/proc%5C/.*%5C/stat%5C%22/

The only way to parse it is to do strrchr(')') first (fortunately it
contains just one unescaped string).

What is old is new again. Perhaps it's a good time to reflect on the
security of relying on VFS-based gadgets for process and system
instrumentation.

Long live sysctl.

At the very least, procfs could be taught to expose machine-readable
formats based on file extension.

For JSON, /proc/<pid>/maps.json
For XML, /proc/<pid>/stat.xml

And the like.

-- 
Shawn Webb
Cofounder / Security Engineer
HardenedBSD

https://git.hardenedbsd.org/hardenedbsd/pubkeys/-/raw/master/Shawn_Webb/03A4CBEBB82EA5A67D9F3853FF2E67A277F8E1FA.pub.asc

Attachment: signature.asc
Description:


Current thread: