mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-30 05:47:59 +00:00
remap includes to do {}{} link the profiles use {profile}{profile}
This commit is contained in:
parent
e06d1bf84b
commit
fe5a2b35ee
@ -2647,7 +2647,7 @@ sub UI_SelectUpdatedRepoProfile ($$) {
|
||||
if ($ans eq "CMD_UPDATE_PROFILE") {
|
||||
eval {
|
||||
my $profile_data =
|
||||
parse_profile_data($p->{profile}, "repository profile");
|
||||
parse_profile_data($p->{profile}, "repository profile", 0);
|
||||
if ($profile_data) {
|
||||
attach_profile_data(\%sd, $profile_data);
|
||||
$changed{$profile} = 1;
|
||||
@ -2808,7 +2808,7 @@ sub parse_repo_profile {
|
||||
my ($fqdbin, $repo_url, $profile) = @_;
|
||||
|
||||
my $profile_data = eval {
|
||||
parse_profile_data($profile->{profile}, "repository profile");
|
||||
parse_profile_data($profile->{profile}, "repository profile", 0);
|
||||
};
|
||||
if ($@) {
|
||||
print STDERR "PARSING ERROR: $@\n";
|
||||
@ -3550,14 +3550,14 @@ sub delete_duplicates (\%$) {
|
||||
# of deny with different perms.
|
||||
|
||||
## network rules
|
||||
$deleted += delete_net_duplicates($profile->{allow}{netdomain}, $include{$incname}{allow}{netdomain});
|
||||
$deleted += delete_net_duplicates($profile->{deny}{netdomain}, $include{$incname}{deny}{netdomain});
|
||||
$deleted += delete_net_duplicates($profile->{allow}{netdomain}, $include{$incname}{$incname}{allow}{netdomain});
|
||||
$deleted += delete_net_duplicates($profile->{deny}{netdomain}, $include{$incname}{$incname}{deny}{netdomain});
|
||||
|
||||
## capabilities
|
||||
$deleted += delete_cap_duplicates($profile->{allow}{capability},
|
||||
$include{$incname}{allow}{capability});
|
||||
$include{$incname}{$incname}{allow}{capability});
|
||||
$deleted += delete_cap_duplicates($profile->{deny}{capability},
|
||||
$include{$incname}{deny}{capability});
|
||||
$include{$incname}{$incname}{deny}{capability});
|
||||
|
||||
## paths
|
||||
$deleted += delete_path_duplicates($profile, $incname, 'allow');
|
||||
@ -3577,11 +3577,11 @@ sub matchnetinclude ($$$) {
|
||||
while (my $name = shift @includelist) {
|
||||
push @checked, $name;
|
||||
return 1
|
||||
if netrules_access_check($include{$name}{allow}{netdomain}, $family, $type);
|
||||
if netrules_access_check($include{$name}{$name}{allow}{netdomain}, $family, $type);
|
||||
# if this fragment includes others, check them too
|
||||
if (keys %{ $include{$name}{include} } &&
|
||||
if (keys %{ $include{$name}{$name}{include} } &&
|
||||
(grep($name, @checked) == 0) ) {
|
||||
push @includelist, keys %{ $include{$name}{include} };
|
||||
push @includelist, keys %{ $include{$name}{$name}{include} };
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -3611,8 +3611,8 @@ sub matchcapincludes (\%$) {
|
||||
next if ($includevalid == 0);
|
||||
|
||||
push @newincludes, $incname
|
||||
if ( defined $include{$incname}{allow}{capability}{$cap}{set} &&
|
||||
$include{$incname}{allow}{capability}{$cap}{set} == 1 );
|
||||
if ( defined $include{$incname}{$incname}{allow}{capability}{$cap}{set} &&
|
||||
$include{$incname}{$incname}{allow}{capability}{$cap}{set} == 1 );
|
||||
}
|
||||
return @newincludes;
|
||||
}
|
||||
@ -4223,7 +4223,7 @@ sub readprofile ($$$) {
|
||||
close(SDPROF);
|
||||
|
||||
eval {
|
||||
my $profile_data = parse_profile_data($data, $file);
|
||||
my $profile_data = parse_profile_data($data, $file, 0);
|
||||
if ($profile_data && $active_profile) {
|
||||
attach_profile_data(\%sd, $profile_data);
|
||||
attach_profile_data(\%original_sd, $profile_data);
|
||||
@ -4253,12 +4253,18 @@ sub attach_profile_data {
|
||||
}
|
||||
|
||||
sub parse_profile_data {
|
||||
my ($data, $file) = @_;
|
||||
my ($data, $file, $do_include) = @_;
|
||||
|
||||
|
||||
my ($profile_data, $profile, $hat, $in_contained_hat, $repo_data,
|
||||
@parsed_profiles);
|
||||
my $initial_comment = "";
|
||||
|
||||
if ($do_include) {
|
||||
$profile = $file;
|
||||
$hat = $file;
|
||||
}
|
||||
|
||||
for (split(/\n/, $data)) {
|
||||
chomp;
|
||||
|
||||
@ -4267,6 +4273,9 @@ sub parse_profile_data {
|
||||
|
||||
# start of a profile...
|
||||
if (m/^\s*(("??\/.+?"??)|(profile\s+("??.+?"??)))\s+((flags=)?\((.+)\)\s+)*\{\s*(#.*)?$/) {
|
||||
if ($do_include) {
|
||||
die "include <$file> contains syntax errors.\n";
|
||||
}
|
||||
|
||||
# if we run into the start of a profile while we're already in a
|
||||
# profile, something's wrong...
|
||||
@ -4319,6 +4328,9 @@ sub parse_profile_data {
|
||||
|
||||
# if we hit the end of a profile when we're not in one, something's
|
||||
# wrong...
|
||||
if ($do_include) {
|
||||
die "include <$file> contains syntax errors.";
|
||||
}
|
||||
if (not $profile) {
|
||||
die sprintf(gettext('%s contains syntax errors.'), $file) . "\n";
|
||||
}
|
||||
@ -4423,7 +4435,7 @@ sub parse_profile_data {
|
||||
}
|
||||
|
||||
store_list_var($profile_data->{$profile}{$hat}{lvar}, $list_var, $value);
|
||||
} else {
|
||||
} else {
|
||||
unless (exists $filelist{$file}{lvar}) {
|
||||
# create lval hash by sticking an empty list into list_var
|
||||
my @empty = ();
|
||||
@ -4527,6 +4539,9 @@ sub parse_profile_data {
|
||||
push @{$profile_data->{$profile}{$hat}{allow}{netdomain}{rule}}, $_;
|
||||
|
||||
} elsif (m/^\s*\^(\"??.+?\"??)\s*,\s*(#.*)?$/) {
|
||||
if (not $profile) {
|
||||
die "$file contains syntax errors.";
|
||||
}
|
||||
# change_hat declaration - needed to change_hat to an external
|
||||
# hat
|
||||
$hat = $1;
|
||||
@ -4537,6 +4552,9 @@ sub parse_profile_data {
|
||||
unless exists($profile_data->{$profile}{$hat}{declared});
|
||||
|
||||
} elsif (m/^\s*\^(\"??.+?\"??)\s+(flags=\(.+\)\s+)*\{\s*(#.*)?$/) {
|
||||
if ($do_include) {
|
||||
die "include <$file> contains syntax errors.";
|
||||
}
|
||||
# start of embedded hat syntax hat definition
|
||||
# read in and mark as changed so that will be written out in the new
|
||||
# format
|
||||
@ -4590,8 +4608,8 @@ sub parse_profile_data {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# we hit something we don't understand in a profile...
|
||||
die sprintf(gettext('%s contains syntax errors. Line [%s]'), $file, $_) . "\n";
|
||||
# we hit something we don't understand in a profile...
|
||||
die sprintf(gettext('%s contains syntax errors. Line [%s]'), $file, $_) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -4599,6 +4617,7 @@ sub parse_profile_data {
|
||||
# Cleanup : add required hats if not present in the
|
||||
# parsed profiles
|
||||
#
|
||||
if (not $do_include) {
|
||||
for my $hatglob (keys %{$cfg->{required_hats}}) {
|
||||
for my $parsed_profile ( sort @parsed_profiles ) {
|
||||
if ($parsed_profile =~ /$hatglob/) {
|
||||
@ -4611,8 +4630,8 @@ sub parse_profile_data {
|
||||
}
|
||||
}
|
||||
|
||||
# if we're still in a profile when we hit the end of the file, it's bad
|
||||
if ($profile) {
|
||||
} # if we're still in a profile when we hit the end of the file, it's bad
|
||||
if ($profile and not $do_include) {
|
||||
die "Reached the end of $file while we were still inside the $profile profile.\n";
|
||||
}
|
||||
|
||||
@ -5210,8 +5229,8 @@ sub profile_known_capability (\%$) {
|
||||
return -1 if $profile->{deny}{capability}{$capname}{set};
|
||||
return 1 if $profile->{allow}{capability}{$capname}{set};
|
||||
for my $incname ( keys %{$profile->{include}} ) {
|
||||
return -1 if $include{$incname}{deny}{capability}{$capname}{set};
|
||||
return 1 if $include{$incname}{allow}{capability}{$capname}{set};
|
||||
return -1 if $include{$incname}{$incname}{deny}{capability}{$capname}{set};
|
||||
return 1 if $include{$incname}{$incname}{allow}{capability}{$capname}{set};
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -5225,7 +5244,7 @@ sub profile_known_network (\%$$) {
|
||||
$family, $sock_type);
|
||||
|
||||
for my $incname ( keys %{$profile->{include}} ) {
|
||||
return -1 if netrules_access_check($include{$incname}{deny}{netdomain},
|
||||
return -1 if netrules_access_check($include{$incname}{$incname}{deny}{netdomain},
|
||||
$family, $sock_type);
|
||||
return 1 if netrules_access_check($include{$incname}{allow}{netdomain},
|
||||
$family, $sock_type);
|
||||
@ -5292,86 +5311,17 @@ sub loadinclude {
|
||||
my $which = shift;
|
||||
|
||||
# don't bother loading it again if we already have
|
||||
return 0 if $include{$which};
|
||||
return 0 if $include{$which}{$which};
|
||||
|
||||
my @loadincludes = ($which);
|
||||
while (my $incfile = shift @loadincludes) {
|
||||
|
||||
my $data = get_include_data($incfile);
|
||||
for (split(/\n/, $data)) {
|
||||
chomp;
|
||||
|
||||
if (/^\s*(\$\{?[[:alpha:]][[:alnum:]_]*\}?)\s*=\s*(true|false)\s*$/i) {
|
||||
# boolean definition
|
||||
} elsif (/^\s*(@\{?[[:alpha:]][[:alnum:]_]+\}?)\s*\+=\s*(.+)\s*$/) {
|
||||
# variable additions
|
||||
} elsif (/^\s*(@\{?[[:alpha:]][[:alnum:]_]+\}?)\s*=\s*(.+)\s*$/) {
|
||||
# variable definitions
|
||||
} elsif (m/^\s*if\s+(not\s+)?(\$\{?[[:alpha:]][[:alnum:]_]*\}?)\s*\{\s*$/) {
|
||||
# conditional -- boolean
|
||||
} elsif (m/^\s*if\s+(not\s+)?defined\s+(@\{?[[:alpha:]][[:alnum:]_]+\}?)\s*\{\s*$/) {
|
||||
# conditional -- variable defined
|
||||
} elsif (m/^\s*if\s+(not\s+)?defined\s+(\$\{?[[:alpha:]][[:alnum:]_]+\}?)\s*\{\s*$/) {
|
||||
# conditional -- boolean defined
|
||||
} elsif (m/^\s*\}\s*$/) {
|
||||
# end of a profile or conditional
|
||||
} elsif (m/^\s*([\"\@\/].*)\s+(\S+)\s*,\s*$/) {
|
||||
# path entry
|
||||
|
||||
my ($path, $mode) = ($1, $2);
|
||||
|
||||
# strip off any trailing spaces.
|
||||
$path =~ s/\s+$//;
|
||||
|
||||
$path = strip_quotes($path);
|
||||
|
||||
# make sure they don't have broken regexps in the profile
|
||||
my $p_re = convert_regexp($path);
|
||||
eval { "foo" =~ m/^$p_re$/; };
|
||||
if ($@) {
|
||||
die sprintf(gettext('Include file %s contains invalid regexp %s.'),
|
||||
$incfile, $path) . "\n";
|
||||
}
|
||||
|
||||
if (!validate_profile_mode($mode, 'allow')) {
|
||||
fatal_error(sprintf(gettext('Include file %s contains invalid mode %s.'), $incfile, $mode));
|
||||
}
|
||||
|
||||
$include{$incfile}{allow}{path}{$path}{mode} = str_to_mode($mode);
|
||||
} elsif (/^\s*capability\s+(.+)\s*,\s*$/) {
|
||||
|
||||
my $capability = $1;
|
||||
$include{$incfile}{allow}{capability}{$capability}{set} = 1;
|
||||
|
||||
} elsif (/^\s*#include <(.+)>\s*$/) {
|
||||
# include stuff
|
||||
|
||||
my $newinclude = $1;
|
||||
push @loadincludes, $newinclude unless $include{$newinclude};
|
||||
$include{$incfile}{include}{$newinclude} = 1;
|
||||
|
||||
} elsif (/^\s*(tcp_connect|tcp_accept|udp_send|udp_receive)/) {
|
||||
} elsif (/^\s*network/) {
|
||||
if ( /^\s*network\s+(\S+)\s*,\s*$/ ) {
|
||||
$include{$incfile}{allow}{netdomain}{rule}{$1} = 1;
|
||||
} elsif ( /^\s*network\s+(\S+)\s+(\S+)\s*,\s*$/ ) {
|
||||
$include{$incfile}{allow}{netdomain}{rule}{$1}{$2} = 1;
|
||||
} else {
|
||||
$include{$incfile}{allow}{netdomain}{rule}{all} = 1;
|
||||
}
|
||||
} else {
|
||||
|
||||
# we don't care about blank lines or comments
|
||||
next if /^\s*$/;
|
||||
next if /^\s*\#/;
|
||||
|
||||
# we hit something we don't understand in a profile...
|
||||
die sprintf(gettext('Include file %s contains syntax errors or is not a valid #include file.'), $incfile) . "\n";
|
||||
}
|
||||
}
|
||||
close(INCLUDE);
|
||||
my $incdata = parse_profile_data($data, $incfile, 1);
|
||||
if ($incdata) {
|
||||
attach_profile_data(\%include, $incdata);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -5407,20 +5357,20 @@ sub match_include_to_path ($$$) {
|
||||
while (my $incfile = shift @includelist) {
|
||||
my $ret = eval { loadinclude($incfile); };
|
||||
if ($@) { fatal_error $@; }
|
||||
my ($cm, @m) = rematchfrag($include{$incfile}, $allow, $path);
|
||||
my ($cm, @m) = rematchfrag($include{$incfile}{$incfile}, $allow, $path);
|
||||
if ($cm) {
|
||||
$combinedmode |= $cm;
|
||||
push @matches, @m;
|
||||
}
|
||||
|
||||
# check if a literal version is in the current include fragment
|
||||
if ($include{$incfile}{$allow}{path}{$path}) {
|
||||
$combinedmode |= $include{$incfile}{$allow}{path}{$path}{mode};
|
||||
if ($include{$incfile}{$incfile}{$allow}{path}{$path}) {
|
||||
$combinedmode |= $include{$incfile}{$incfile}{$allow}{path}{$path}{mode};
|
||||
}
|
||||
|
||||
# if this fragment includes others, check them too
|
||||
if (keys %{ $include{$incfile}{include} }) {
|
||||
push @includelist, keys %{ $include{$incfile}{include} };
|
||||
if (keys %{ $include{$incfile}{$incfile}{include} }) {
|
||||
push @includelist, keys %{ $include{$incfile}{$incfile}{include} };
|
||||
}
|
||||
}
|
||||
|
||||
@ -5457,20 +5407,20 @@ sub suggest_incs_for_path {
|
||||
# scan the include fragments looking for matches
|
||||
my @includelist = ($incname);
|
||||
while (my $include = shift @includelist) {
|
||||
my ($cm, @m) = rematchfrag($include{$include}, 'allow', $path);
|
||||
my ($cm, @m) = rematchfrag($include{$include}{$include}, 'allow', $path);
|
||||
if ($cm) {
|
||||
$combinedmode |= $cm;
|
||||
push @matches, @m;
|
||||
}
|
||||
|
||||
# check if a literal version is in the current include fragment
|
||||
if ($include{$include}{allow}{path}{$path}) {
|
||||
$combinedmode |= $include{$include}{allow}{path}{$path}{mode};
|
||||
if ($include{$include}{$include}{allow}{path}{$path}) {
|
||||
$combinedmode |= $include{$include}{$include}{allow}{path}{$path}{mode};
|
||||
}
|
||||
|
||||
# if this fragment includes others, check them too
|
||||
if (keys %{ $include{$include}{include} }) {
|
||||
push @includelist, keys %{ $include{$include}{include} };
|
||||
if (keys %{ $include{$include}{$include}{include} }) {
|
||||
push @includelist, keys %{ $include{$include}{$include}{include} };
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user