mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-31 06:16:03 +00:00
expand automated profile generation to to allow profile generation from stdin
This extends the auto-profile generation so that it can take profiles formated in standard profile language augemented by a few special variables for the automatically generated rules. This will all extended the regression tests in ways that are not currently supported, because mkprofile format does not match of the profile language. the special apparmorish variables are @{gen_elf name} - generate rules for elf binaries @{gen_bin name} - generate rules for a binary @{gen_def} - generate default rules @{gen name} - do @{gen_def} @{gen_bin name} To generate a profile you do genprofile --stdin <<EOF /profile/name { @{gen /profile/name} } EOF eg. to generate the equivalent of genprofile you would do genprofile --stdin <<EOF $test { @{gen $test} } EOF and the equiv of genprofile $file:rw would be genprofile --stdin <<EOF $test { @{gen $test} $file rw, } while it takes a little more to generate a base profile than the old syntax, it use the actual profile language (augmented with the special variables), it is a lot more flexible, and a lot easier to expand when new rule types are added. eg. of something not possible with the current auto generation Generate a profile with a child profile and hat and a trailing profile genprofile --stdin <<EOF $test { @{gen $test} profile $bin/open { @{gen $bin/open} } ^hatfoo { $file rw, } } profile $bin/exec { @{gen $bin/exec} } EOF Signed-off-by: John Johansen <john.johansen@canonical.com> Acked-By: Steve Beattie <sbeattie@ubuntu.com>
This commit is contained in:
@@ -16,6 +16,7 @@ my $nowarn = '';
|
||||
my $nodefault;
|
||||
my $noimage;
|
||||
my $escape = '';
|
||||
my $usestdin = '';
|
||||
my %output_rules;
|
||||
my $hat = "__no_hat";
|
||||
my %flags;
|
||||
@@ -26,19 +27,22 @@ GetOptions(
|
||||
'help|h' => \$help,
|
||||
'nodefault|N' => \$nodefault,
|
||||
'noimage|I' => \$noimage,
|
||||
'stdin' => \$usestdin,
|
||||
);
|
||||
|
||||
sub usage {
|
||||
print STDERR "$__VERSION__\n";
|
||||
print STDERR "Usage $0 [--nowarn|--escape] execname [rules]\n";
|
||||
print STDERR " $0 --help\n";
|
||||
print STDERR " $0 --stdin\n";
|
||||
print STDERR " nowarn: don't warn if execname does not exist\n";
|
||||
print STDERR " nodefault: don't include default rules/ldd output\n";
|
||||
print STDERR " escape: escape stuff that would be treated as regexs\n";
|
||||
print STDERR " help: print this message\n";
|
||||
}
|
||||
|
||||
&usage && exit 0 if ($help || @ARGV < 1);
|
||||
# genprofile passes in $bin:w as default rule atm
|
||||
&usage && exit 0 if ($help || (!$usestdin && @ARGV < 1) || ($usestdin && @ARGV != 2));
|
||||
|
||||
sub head ($) {
|
||||
my $file = shift;
|
||||
@@ -214,34 +218,6 @@ sub gen_addimage($) {
|
||||
}
|
||||
}
|
||||
|
||||
my $bin = shift @ARGV;
|
||||
!(-e $bin || $nowarn) && print STDERR "Warning: execname '$bin': no such file or directory\n";
|
||||
|
||||
unless ($nodefault) {
|
||||
gen_default_rules();
|
||||
gen_binary($bin);
|
||||
}
|
||||
|
||||
for my $rule (@ARGV) {
|
||||
#($fn, @rules) = split (/:/, $rule);
|
||||
if ($rule =~ /^(tcp|udp)/) {
|
||||
# netdomain rules
|
||||
gen_netdomain($rule);
|
||||
} elsif ($rule =~ /^network:/) {
|
||||
gen_network($rule);
|
||||
} elsif ($rule =~ /^cap:/) {
|
||||
gen_cap($rule);
|
||||
} elsif ($rule =~ /^flag:/) {
|
||||
gen_flag($rule);
|
||||
} elsif ($rule =~ /^hat:/) {
|
||||
gen_hat($rule);
|
||||
} elsif ($rule =~ /^addimage:/) {
|
||||
gen_addimage($rule);
|
||||
} else {
|
||||
gen_file($rule);
|
||||
}
|
||||
}
|
||||
|
||||
sub emit_flags($) {
|
||||
my $hat = shift;
|
||||
|
||||
@@ -255,26 +231,99 @@ sub emit_flags($) {
|
||||
}
|
||||
}
|
||||
|
||||
print STDOUT "# Profile autogenerated by $__VERSION__\n";
|
||||
print STDOUT "$bin ";
|
||||
emit_flags('__no_hat');
|
||||
print STDOUT "{\n";
|
||||
foreach my $outrule (@{$output_rules{'__no_hat'}}) {
|
||||
print STDOUT $outrule;
|
||||
}
|
||||
foreach my $hat (keys %output_rules) {
|
||||
if (not $hat =~ /^__no_hat$/) {
|
||||
print STDOUT "\n ^$hat";
|
||||
emit_flags($hat);
|
||||
print STDOUT " {\n";
|
||||
foreach my $outrule (@{$output_rules{$hat}}) {
|
||||
print STDOUT " $outrule";
|
||||
# generate profiles based on cmd line arguments
|
||||
sub gen_from_args() {
|
||||
my $bin = shift @ARGV;
|
||||
!(-e $bin || $nowarn) && print STDERR "Warning: execname '$bin': no such file or directory\n";
|
||||
|
||||
unless ($nodefault) {
|
||||
gen_default_rules();
|
||||
gen_binary($bin);
|
||||
}
|
||||
|
||||
for my $rule (@ARGV) {
|
||||
#($fn, @rules) = split (/:/, $rule);
|
||||
if ($rule =~ /^(tcp|udp)/) {
|
||||
# netdomain rules
|
||||
gen_netdomain($rule);
|
||||
} elsif ($rule =~ /^network:/) {
|
||||
gen_network($rule);
|
||||
} elsif ($rule =~ /^cap:/) {
|
||||
gen_cap($rule);
|
||||
} elsif ($rule =~ /^flag:/) {
|
||||
gen_flag($rule);
|
||||
} elsif ($rule =~ /^hat:/) {
|
||||
gen_hat($rule);
|
||||
} elsif ($rule =~ /^addimage:/) {
|
||||
gen_addimage($rule);
|
||||
} else {
|
||||
gen_file($rule);
|
||||
}
|
||||
}
|
||||
|
||||
print STDOUT "# Profile autogenerated by $__VERSION__\n";
|
||||
print STDOUT "$bin ";
|
||||
emit_flags('__no_hat');
|
||||
print STDOUT "{\n";
|
||||
foreach my $outrule (@{$output_rules{'__no_hat'}}) {
|
||||
print STDOUT $outrule;
|
||||
}
|
||||
foreach my $hat (keys %output_rules) {
|
||||
if (not $hat =~ /^__no_hat$/) {
|
||||
print STDOUT "\n ^$hat";
|
||||
emit_flags($hat);
|
||||
print STDOUT " {\n";
|
||||
foreach my $outrule (@{$output_rules{$hat}}) {
|
||||
print STDOUT " $outrule";
|
||||
}
|
||||
print STDOUT " }\n";
|
||||
}
|
||||
}
|
||||
#foreach my $hat keys
|
||||
#foreach my $outrule (@output_rules) {
|
||||
# print STDOUT $outrule;
|
||||
#}
|
||||
print STDOUT "}\n";
|
||||
}
|
||||
|
||||
#generate the profiles from stdin, interpreting and replacing the following sequences
|
||||
# @{gen_elf name} - generate rules for elf binaries
|
||||
# @{gen_bin name} - generate rules for a binary
|
||||
# @{gen_def} - generate default rules
|
||||
# @{gen name} - do @{gen_def} @{gen_bin name}
|
||||
|
||||
sub emit_and_clear_rules() {
|
||||
foreach my $outrule (@{$output_rules{'__no_hat'}}) {
|
||||
print STDOUT $outrule;
|
||||
}
|
||||
|
||||
undef %output_rules;
|
||||
}
|
||||
|
||||
sub gen_from_stdin() {
|
||||
while(<STDIN>) {
|
||||
chomp;
|
||||
if ($_ =~ m/@\{gen_def}/) {
|
||||
gen_default_rules();
|
||||
emit_and_clear_rules();
|
||||
} elsif ($_ =~ m/@\{gen_bin\s+(.+)\}/) {
|
||||
gen_binary($1);
|
||||
emit_and_clear_rules();
|
||||
} elsif ($_ =~ m/@\{gen_elf\s+(.+)\}/) {
|
||||
gen_elf_binary($1);
|
||||
emit_and_clear_rules();
|
||||
} elsif ($_ =~ m/@\{gen\s+(.+)\}/) {
|
||||
gen_default_rules();
|
||||
gen_binary($1);
|
||||
emit_and_clear_rules();
|
||||
} else {
|
||||
print STDOUT "$_\n" ;
|
||||
}
|
||||
print STDOUT " }\n";
|
||||
}
|
||||
}
|
||||
#foreach my $hat keys
|
||||
#foreach my $outrule (@output_rules) {
|
||||
# print STDOUT $outrule;
|
||||
#}
|
||||
print STDOUT "}\n";
|
||||
|
||||
if ($usestdin) {
|
||||
gen_from_stdin();
|
||||
} else {
|
||||
gen_from_args();
|
||||
}
|
||||
|
Reference in New Issue
Block a user