From: "Tobin C. Harding" <me@tobin.cc>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: "Tobin C. Harding" <me@tobin.cc>,
"Jason A. Donenfeld" <Jason@zx2c4.com>,
Theodore Ts'o <tytso@mit.edu>, Kees Cook <keescook@chromium.org>,
Paolo Bonzini <pbonzini@redhat.com>,
Tycho Andersen <tycho@docker.com>,
"Roberts, William C" <william.c.roberts@intel.com>,
Tejun Heo <tj@kernel.org>,
Jordan Glover <Golden_Miller83@protonmail.ch>,
Greg KH <gregkh@linuxfoundation.org>,
Petr Mladek <pmladek@suse.com>, Joe Perches <joe@perches.com>,
Ian Campbell <ijc@hellion.org.uk>,
Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <wil.deacon@arm.com>,
Steven Rostedt <rostedt@goodmis.org>,
Chris Fries <cfries@google.com>,
Dave Weinstein <olorin@google.com>,
Daniel Micay <danielmicay@gmail.com>,
Subject: [PATCH v2 6/8] scripts/leaking_addresses: add summary reporting
Date: Thu, 9 Nov 2017 16:09:33 +1100 [thread overview]
Message-ID: <1510204175-10138-7-git-send-email-me@tobin.cc> (raw)
In-Reply-To: <1510204175-10138-1-git-send-email-me@tobin.cc>
Currently script just dumps all results found. Potentially, this risks
losing single results among multiple duplicate results. We need some
way of restricting duplicates to assist users of the script. It would
also be nice if we got a report instead of raw results.
Duplicates can be defined in various ways, instead of trying to find a
single perfect solution we can present the user with various options to
display the output. Doing so will typically lead to users wanting to
view the output multiple times. Currently we scan the kernel each time,
this is slow and unnecessary. We can expedite the process by writing the
results to file for subsequent viewing.
Add command line options to enable summary reporting, including options
to write to and read from file.
Signed-off-by: Tobin C. Harding <me@tobin.cc>
---
scripts/leaking_addresses.pl | 191 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 188 insertions(+), 3 deletions(-)
diff --git a/scripts/leaking_addresses.pl b/scripts/leaking_addresses.pl
index 0aac03a020a8..4610ad3c80c2 100755
--- a/scripts/leaking_addresses.pl
+++ b/scripts/leaking_addresses.pl
@@ -31,6 +31,13 @@ my @DIRS = ('/proc', '/sys');
# 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.
# Do not parse these files (absolute path).
my @skip_parse_files_abs = ('/proc/kmsg',
@@ -73,13 +80,31 @@ sub help
my ($exitcode) = @_;
print << "EOM";
+
Usage: $P [OPTIONS]
Version: $V
Options:
- -d, --debug Display debugging output.
- -h, --help, --version Display this help and exit.
+ -o, --output-raw=<file> Save results for future processing.
+ -i, --input-raw=<file> Read results from file instead of scanning.
+ --raw Show raw results (default).
+ --suppress-dmesg Do not show dmesg results.
+ --squash-by-path Show one result per unique path.
+ --squash-by-filename Show one result per unique filename.
+ -d, --debug Display debugging output.
+ -h, --help, --version Display this help and exit.
+
+Examples:
+
+ # Scan kernel and dump raw results.
+ $0
+
+ # Scan kernel and save results to file.
+ $0 --output-raw scan.out
+
+ # View summary report.
+ $0 --input-raw scan.out --squash-by-filename
Scans the running (64 bit) kernel for potential leaking addresses.
@@ -90,11 +115,33 @@ EOM
GetOptions(
'd|debug' => \$debug,
'h|help' => \$help,
- 'version' => \$help
+ 'version' => \$help,
+ 'o|output-raw=s' => \$output_raw,
+ 'i|input-raw=s' => \$input_raw,
+ 'suppress-dmesg' => \$suppress_dmesg,
+ 'squash-by-path' => \$squash_by_path,
+ 'squash-by-filename' => \$squash_by_filename,
+ 'raw' => \$raw,
) or help(1);
help(0) if ($help);
+if ($input_raw) {
+ format_output($input_raw);
+ exit(0);
+}
+
+if (!$input_raw and ($squash_by_path or $squash_by_filename)) {
+ printf "\nSummary reporting only available with --input-raw=<file>\n";
+ printf "(First run scan with --output-raw=<file>.)\n";
+ exit(128);
+}
+
+if ($output_raw) {
+ open my $fh, '>', $output_raw or die "$0: $output_raw: $!\n";
+ select $fh;
+}
+
parse_dmesg();
walk(@DIRS);
@@ -239,3 +286,141 @@ sub walk
}
}
}
+
+sub format_output
+{
+ my ($file) = @_;
+
+ # Default is to show raw results.
+ if ($raw or (!$squash_by_path and !$squash_by_filename)) {
+ dump_raw_output($file);
+ return;
+ }
+
+ my ($total, $dmesg, $paths, $files) = parse_raw_file($file);
+
+ printf "\nTotal number of results from scan (incl dmesg): %d\n", $total;
+
+ if (!$suppress_dmesg) {
+ print_dmesg($dmesg);
+ }
+
+ if ($squash_by_filename) {
+ squash_by($files, 'filename');
+ }
+
+ if ($squash_by_path) {
+ squash_by($paths, 'path');
+ }
+}
+
+sub dump_raw_output
+{
+ my ($file) = @_;
+
+ open (my $fh, '<', $file) or die "$0: $file: $!\n";
+ while (<$fh>) {
+ if ($suppress_dmesg) {
+ if ("dmesg:" eq substr($_, 0, 6)) {
+ next;
+ }
+ }
+ print $_;
+ }
+ close $fh;
+}
+
+sub parse_raw_file
+{
+ my ($file) = @_;
+
+ my $total = 0; # Total number of lines parsed.
+ my @dmesg; # dmesg output.
+ my %files; # Unique filenames containing leaks.
+ my %paths; # Unique paths containing leaks.
+
+ open (my $fh, '<', $file) or die "$0: $file: $!\n";
+ while (my $line = <$fh>) {
+ $total++;
+
+ if ("dmesg:" eq substr($line, 0, 6)) {
+ push @dmesg, $line;
+ next;
+ }
+
+ cache_path(\%paths, $line);
+ cache_filename(\%files, $line);
+ }
+
+ return $total, \@dmesg, \%paths, \%files;
+}
+
+sub print_dmesg
+{
+ my ($dmesg) = @_;
+
+ print "\ndmesg output:\n";
+
+ if (@$dmesg == 0) {
+ print "<no results>\n";
+ return;
+ }
+
+ foreach(@$dmesg) {
+ my $index = index($_, ': ');
+ $index += 2; # skid ': '
+ print substr($_, $index);
+ }
+}
+
+sub squash_by
+{
+ my ($ref, $desc) = @_;
+
+ print "\nResults squashed by $desc (excl dmesg). ";
+ print "Displaying [<number of results> <$desc>], <example result>\n";
+
+ if (keys %$ref == 0) {
+ print "<no results>\n";
+ return;
+ }
+
+ foreach(keys %$ref) {
+ my $lines = $ref->{$_};
+ my $length = @$lines;
+ printf "[%d %s] %s", $length, $_, @$lines[0];
+ }
+}
+
+sub cache_path
+{
+ my ($paths, $line) = @_;
+
+ my $index = index($line, ': ');
+ my $path = substr($line, 0, $index);
+
+ $index += 2; # skip ': '
+ add_to_cache($paths, $path, substr($line, $index));
+}
+
+sub cache_filename
+{
+ my ($files, $line) = @_;
+
+ my $index = index($line, ': ');
+ my $path = substr($line, 0, $index);
+ my $filename = basename($path);
+
+ $index += 2; # skip ': '
+ add_to_cache($files, $filename, substr($line, $index));
+}
+
+sub add_to_cache
+{
+ my ($cache, $key, $value) = @_;
+
+ if (!$cache->{$key}) {
+ $cache->{$key} = ();
+ }
+ push @{$cache->{$key}}, $value;
+}
--
2.7.4
next prev parent reply other threads:[~2017-11-09 5:09 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-09 5:09 [PATCH v2 0/8] scripts/leaking_addresses: add summary reporting Tobin C. Harding
2017-11-09 5:09 ` [PATCH v2 1/8] scripts/leaking_addresses: use tabs not spaces Tobin C. Harding
2017-11-09 5:09 ` [PATCH v2 2/8] scripts/leaking_addresses: remove dead code Tobin C. Harding
2017-11-09 5:09 ` [PATCH v2 3/8] scripts/leaking_addresses: remove command line options Tobin C. Harding
2017-11-09 5:09 ` [PATCH v2 4/8] scripts/leaking_addresses: fix comment typo Tobin C. Harding
2017-11-09 5:09 ` [PATCH v2 5/8] scripts/leaking_addresses: add to exclude files/paths Tobin C. Harding
2017-11-09 5:09 ` Tobin C. Harding [this message]
2017-11-09 5:09 ` [PATCH v2 7/8] scripts/leaking_addresses: add support for ppc64 Tobin C. Harding
2017-11-09 5:09 ` [PATCH v2 8/8] scripts/leaking_addresses: add timeout on file read Tobin C. Harding
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1510204175-10138-7-git-send-email-me@tobin.cc \
--to=me@tobin.cc \
--cc=Golden_Miller83@protonmail.ch \
--cc=Jason@zx2c4.com \
--cc=catalin.marinas@arm.com \
--cc=cfries@google.com \
--cc=danielmicay@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=ijc@hellion.org.uk \
--cc=joe@perches.com \
--cc=keescook@chromium.org \
--cc=olorin@google.com \
--cc=pbonzini@redhat.com \
--cc=pmladek@suse.com \
--cc=rostedt@goodmis.org \
--cc=sergey.senozhatsky@gmail.com \
--cc=tj@kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=tycho@docker.com \
--cc=tytso@mit.edu \
--cc=wil.deacon@arm.com \
--cc=william.c.roberts@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).