Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
leaking_addresses.pl 12.80 KiB
#!/usr/bin/env perl
# SPDX-License-Identifier: GPL-2.0-only
#
# (c) 2017 Tobin C. Harding <me@tobin.cc>
#
# leaking_addresses.pl: Scan the kernel for potential leaking addresses.
#  - Scans dmesg output.
#  - Walks directory tree and parses each file (for each directory in @DIRS).
#
# Use --debug to output path before parsing, this is useful to find files that
# cause the script to choke.

#
# 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 exclude all PID directories under /proc except '1/'

use warnings;
use strict;
use POSIX;
use File::Basename;
use File::Spec;
use Cwd 'abs_path';
use Term::ANSIColor qw(:constants);
use Getopt::Long qw(:config no_auto_abbrev);
use Config;
use bigint qw/hex/;
use feature 'state';

my $P = $0;

# Directories to scan.
my @DIRS = ('/proc', '/sys');

# Timer for parsing each file, in seconds.
my $TIMEOUT = 10;

# Kernel addresses vary by architecture.  We can only auto-detect the following
# architectures (using `uname -m`).  (flag --32-bit overrides auto-detection.)
my @SUPPORTED_ARCHITECTURES = ('x86_64', 'ppc64', 'x86');

# Command line options.
my $help = 0;
my $debug = 0;
my $raw = 0;
my $output_raw = "";	# Write raw results to file.
my $input_raw = "";	# Read raw results from file instead of scanning.
my $suppress_dmesg = 0;		# Don't show dmesg in output.
my $squash_by_path = 0;		# Summary report grouped by absolute path.
my $squash_by_filename = 0;	# Summary report grouped by filename.
my $kernel_config_file = "";	# Kernel configuration file.
my $opt_32bit = 0;		# Scan 32-bit kernel.
my $page_offset_32bit = 0;	# Page offset for 32-bit kernel.

# Skip these absolute paths.
my @skip_abs = (
	'/proc/kmsg',
	'/proc/device-tree',
	'/proc/1/syscall',
	'/sys/firmware/devicetree',
	'/sys/kernel/debug/tracing/trace_pipe',
	'/sys/kernel/security/apparmor/revision');

# Skip these under any subdirectory.
my @skip_any = (
	'pagemap',
	'events',