Introduce --kallsyms argument for scanning binary files for known symbol
addresses. This would have found the exposure in /sys/kernel/notes:
$ scripts/leaking_addresses.pl --kallsyms=<(sudo cat /proc/kallsyms)
/sys/kernel/notes: hypercall_page @ 156
/sys/kernel/notes: xen_hypercall_set_trap_table @ 156
/sys/kernel/notes: startup_xen @ 132
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Tycho Andersen <tandersen@netflix.com>
Link: https://lore.kernel.org/r/20240222220053.1475824-4-keescook@chromium.org
Signed-off-by: Kees Cook <keescook@chromium.org>
These are false positives from the input subsystem:
/proc/bus/input/devices: B: KEY=402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe
/sys/devices/platform/i8042/serio0/input/input1/uevent: KEY=402000000 3803078f800d001 feffffdfffefffff fffffffffffffffe
/sys/devices/platform/i8042/serio0/input/input1/capabilities/key: 402000000 3803078f800d001 feffffdf
Pass in the filename for more context and expand the "ignored pattern"
matcher to notice these.
Reviewed-by: Tycho Andersen <tandersen@netflix.com>
Link: https://lore.kernel.org/r/20240222220053.1475824-3-keescook@chromium.org
Signed-off-by: Kees Cook <keescook@chromium.org>
The canonical location for the tracefs filesystem is at /sys/kernel/tracing.
But, from Documentation/trace/ftrace.rst:
Before 4.1, all ftrace tracing control files were within the debugfs
file system, which is typically located at /sys/kernel/debug/tracing.
For backward compatibility, when mounting the debugfs file system,
the tracefs file system will be automatically mounted at:
/sys/kernel/debug/tracing
scripts/leaking_addresses.pl only skipped this older debugfs path, so
let's add the canonical path as well.
Link: https://lkml.kernel.org/r/20230313211746.1541525-2-zwisler@kernel.org
Cc: "Tobin C. Harding" <me@tobin.cc>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Shuah Khan <shuah@kernel.org>
Acked-by: Tycho Andersen <tycho@tycho.pizza>
Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Ross Zwisler <zwisler@google.com>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Recently attempt to remove the '--version' flag was made, badly. We
failed to remove mention of it from the help output. And we (me) failed
to actually remove the flag from the options list.
_Completely_ remove --version flag.
Currently calls to function dprint() are non uniform and at times
incorrect.
Use uniform _correct_ call to function dprint().
Signed-off-by: Tobin C. Harding <tobin@kernel.org>
Sometimes files may be created by using output from printk. As the scan
traverses the directory tree we should parse each path name and check if
it is leaking an address.
Add check for leaking address on each path name.
Suggested-by: Tycho Andersen <tycho@tycho.ws>
Acked-by: Tycho Andersen <tycho@tycho.ws>
Signed-off-by: Tobin C. Harding <me@tobin.cc>
Currently sub routine may_leak_address() is checking regex against Perl
special variable $_ which is _fortunately_ being set correctly in a loop
before this sub routine is called. We already have declared a variable
to hold this value '$line' we should use it.
Use $line in regex match instead of implicit $_
Signed-off-by: Tobin C. Harding <me@tobin.cc>
We have git now, we don't need a version number. This was originally
added because leaking_addresses.pl shamelessly (and mindlessly) copied
checkpatch.pl
Remove version number from script.
Signed-off-by: Tobin C. Harding <me@tobin.cc>
The pointers listed in /proc/1/syscall are user pointers, and negative
syscall args will show up like kernel addresses.
For example
/proc/31808/syscall: 0 0x3 0x55b107a38180 0x2000 0xffffffffffffffb0 \
0x55b107a302d0 0x55b107a38180 0x7fffa313b8e8 0x7ff098560d11
Skip parsing /proc/1/syscall
Suggested-by: Tycho Andersen <tycho@tycho.ws>
Signed-off-by: Tobin C. Harding <me@tobin.cc>
When the system is idle it is likely that most files under /proc/PID
will be identical for various processes. Scanning _all_ the PIDs under
/proc is unnecessary and implies that we are thoroughly scanning /proc.
This is _not_ the case because there may be ways userspace can trigger
creation of /proc files that leak addresses but were not present during
a scan. For these two reasons we should exclude all PID directories
under /proc except '1/'
Exclude all /proc/PID except /proc/1.
Signed-off-by: Tobin C. Harding <me@tobin.cc>
Currently we are repeatedly calling `uname -m`. This is causing the
script to take a long time to run (more than 10 seconds to parse
/proc/kallsyms). We can use Perl state variables to cache the result of
the first call to `uname -m`. With this change in place the script
scans the whole kernel in under a minute.
Cache machine architecture in state variable.
Signed-off-by: Tobin C. Harding <me@tobin.cc>
Currently script has multiple configuration arrays. This is confusing,
evident by the fact that a bunch of the entries are in the wrong place.
We can simplify the code by just having a single array for absolute
paths to skip and a single array for file names to skip wherever they
appear in the scanned directory tree. There are also currently multiple
subroutines to handle the different arrays, we can reduce these to a
single subroutine also.
Simplify the path skipping code.
Signed-off-by: Tobin C. Harding <me@tobin.cc>
Currently script parses binary files. Since we are scanning for
readable kernel addresses there is no need to parse binary files. We
can use Perl to check if file is binary and skip parsing it if so.
Do not parse binary files.
Signed-off-by: Tobin C. Harding <me@tobin.cc>
Currently script only supports x86_64 and ppc64. It would be nice to be
able to scan 32-bit machines also. We can add support for 32-bit
architectures by modifying how we check for false positives, taking
advantage of the page offset used by the kernel, and using the correct
regular expression.
Support for 32-bit machines is enabled by the observation that the kernel
addresses on 32-bit machines are larger [in value] than the page offset.
We can use this to filter false positives when scanning the kernel for
leaking addresses.
Programmatic determination of the running architecture is not
immediately obvious (current 32-bit machines return various strings from
`uname -m`). We therefore provide a flag to enable scanning of 32-bit
kernels. Also we can check the kernel config file for the offset and if
not found default to 0xc0000000. A command line option to parse in the
page offset is also provided. We do automatically detect architecture
if running on ix86.
Add support for 32-bit kernels. Add a command line option for page
offset.
Suggested-by: Kaiwan N Billimoria <kaiwan.billimoria@gmail.com>
Signed-off-by: Tobin C. Harding <me@tobin.cc>
Currently there is duplicate code when checking the architecture type.
We can remove the duplication by implementing a wrapper function
is_arch().
Implement and use wrapper function is_arch().
Signed-off-by: Tobin C. Harding <me@tobin.cc>
Currently script uses Perl to get the machine architecture. This can be
erroneous since Perl uses the architecture of the machine that Perl was
compiled on not the architecture of the running machine. We should use
the systems `uname` command instead.
Use `uname -m` instead of Perl to get the machine architecture.
Signed-off-by: Tobin C. Harding <me@tobin.cc>
Currently script only supports 4 page table levels because of the way
the kernel address regular expression is crafted. We can do better than
this. Using previously added support for kernel configuration options we
can get the number of page table levels defined by
CONFIG_PGTABLE_LEVELS. Using this value a correct regular expression can
be crafted. This only supports 5 page tables on x86_64.
Add support for 5 page table levels on x86_64.
Signed-off-by: Tobin C. Harding <me@tobin.cc>
Features that rely on the ability to get kernel configuration options
are ready to be implemented in script. In preparation for this we can
add support for kernel config options as a separate patch to ease
review.
Add support for locating and parsing kernel configuration file.
Signed-off-by: Tobin C. Harding <me@tobin.cc>
Currently script checks only first and last address in the vsyscall
memory range. We can do better than this. When checking for false
positives against $match, we can convert $match to a hexadecimal value
then check if it lies within the range of vsyscall addresses.
Check whole range of vsyscall addresses when checking for false
positive.
Signed-off-by: Tobin C. Harding <me@tobin.cc>
A number of the command line options to script are dependant on the
option --input-raw being set. If we indent these options it makes
explicit this dependency.
Indent options dependant on --input-raw.
Signed-off-by: Tobin C. Harding <me@tobin.cc>
Currently help output includes command examples. These were cute when we
first started development of this script but are unnecessary.
Remove command examples.
Signed-off-by: Tobin C. Harding <me@tobin.cc>
leaking_addresses.pl can be run with kptr_restrict==0 now, we don't need
the comment about setting kptr_restrict any more.
Remove comment suggesting setting kptr_restrict.
Signed-off-by: Tobin C. Harding <me@tobin.cc>