check-file-access: Allow specifying action

The check-file-access.pl script is used to match access list
generated by virtestmock against whitelisted rules stored in
file_access_whitelist.txt. So far the rules are in form:

  $path: $progname: $testname

This is not sufficient because the rule does not take into
account 'action' that caused $path to appear in the list of
accessed files. After this commit the rule can be in new form:

  $path: $action: $progname: $testname

where $action is one from ("open", "fopen", "access", "stat",
"lstat", "connect"). This way the white list can be fine tuned to
allow say access() but not connect().

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
Michal Privoznik 2018-07-09 10:53:17 +02:00
parent 5c9277b6dd
commit 7135cee755
2 changed files with 37 additions and 10 deletions

View File

@ -27,18 +27,21 @@ use warnings;
my $access_file = "test_file_access.txt";
my $whitelist_file = "file_access_whitelist.txt";
my @known_actions = ("open", "fopen", "access", "stat", "lstat", "connect");
my @files;
my @whitelist;
open FILE, "<", $access_file or die "Unable to open $access_file: $!";
while (<FILE>) {
chomp;
if (/^(\S*):\s*(\S*)(\s*:\s*(.*))?$/) {
if (/^(\S*):\s*(\S*):\s*(\S*)(\s*:\s*(.*))?$/) {
my %rec;
${rec}{path} = $1;
${rec}{progname} = $2;
if (defined $4) {
${rec}{testname} = $4;
${rec}{action} = $2;
${rec}{progname} = $3;
if (defined $5) {
${rec}{testname} = $5;
}
push (@files, \%rec);
} else {
@ -52,7 +55,21 @@ while (<FILE>) {
chomp;
if (/^\s*#.*$/) {
# comment
} elsif (/^(\S*):\s*(\S*)(:\s*(\S*)(\s*:\s*(.*))?)?$/ and
grep /^$2$/, @known_actions) {
# $path: $action: $progname: $testname
my %rec;
${rec}{path} = $1;
${rec}{action} = $3;
if (defined $4) {
${rec}{progname} = $4;
}
if (defined $6) {
${rec}{testname} = $6;
}
push (@whitelist, \%rec);
} elsif (/^(\S*)(:\s*(\S*)(\s*:\s*(.*))?)?$/) {
# $path: $progname: $testname
my %rec;
${rec}{path} = $1;
if (defined $3) {
@ -79,6 +96,11 @@ for my $file (@files) {
next;
}
if (defined %${rule}{action} and
not %${file}{action} =~ m/^$rule->{action}$/) {
next;
}
if (defined %${rule}{progname} and
not %${file}{progname} =~ m/^$rule->{progname}$/) {
next;
@ -95,7 +117,7 @@ for my $file (@files) {
if (not $match) {
$error = 1;
print "$file->{path}: $file->{progname}";
print "$file->{path}: $file->{action}: $file->{progname}";
print ": $file->{testname}" if defined %${file}{testname};
print "\n";
}

View File

@ -1,14 +1,17 @@
# This is a whitelist that allows accesses to files not in our
# build directory nor source directory. The records are in the
# following format:
# following formats:
#
# $path: $progname: $testname
# $path: $action: $progname: $testname
#
# All these three are evaluated as perl RE. So to allow /dev/sda
# and /dev/sdb, you can just '/dev/sd[a-b]', or to allow
# All these variables are evaluated as perl RE. So to allow
# /dev/sda and /dev/sdb, you can just '/dev/sd[a-b]', or to allow
# /proc/$pid/status you can '/proc/\d+/status' and so on.
# Moreover, $progname and $testname can be empty, in which which
# case $path is allowed for all tests.
# Moreover, $action, $progname and $testname can be empty, in which
# which case $path is allowed for all tests. However, $action (if
# specified) must be one of "open", "fopen", "access", "stat",
# "lstat", "connect".
/bin/cat: sysinfotest
/bin/dirname: sysinfotest: x86 sysinfo
@ -19,5 +22,7 @@
/etc/hosts
/proc/\d+/status
/etc/passwd: fopen
# This is just a dummy example, DO NOT USE IT LIKE THAT!
.*: nonexistent-test-touching-everything