mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-31 14:25:52 +00:00
remap includes to do {}{} link the profiles use {profile}{profile}
This commit is contained in:
@@ -2647,7 +2647,7 @@ sub UI_SelectUpdatedRepoProfile ($$) {
|
|||||||
if ($ans eq "CMD_UPDATE_PROFILE") {
|
if ($ans eq "CMD_UPDATE_PROFILE") {
|
||||||
eval {
|
eval {
|
||||||
my $profile_data =
|
my $profile_data =
|
||||||
parse_profile_data($p->{profile}, "repository profile");
|
parse_profile_data($p->{profile}, "repository profile", 0);
|
||||||
if ($profile_data) {
|
if ($profile_data) {
|
||||||
attach_profile_data(\%sd, $profile_data);
|
attach_profile_data(\%sd, $profile_data);
|
||||||
$changed{$profile} = 1;
|
$changed{$profile} = 1;
|
||||||
@@ -2808,7 +2808,7 @@ sub parse_repo_profile {
|
|||||||
my ($fqdbin, $repo_url, $profile) = @_;
|
my ($fqdbin, $repo_url, $profile) = @_;
|
||||||
|
|
||||||
my $profile_data = eval {
|
my $profile_data = eval {
|
||||||
parse_profile_data($profile->{profile}, "repository profile");
|
parse_profile_data($profile->{profile}, "repository profile", 0);
|
||||||
};
|
};
|
||||||
if ($@) {
|
if ($@) {
|
||||||
print STDERR "PARSING ERROR: $@\n";
|
print STDERR "PARSING ERROR: $@\n";
|
||||||
@@ -3550,14 +3550,14 @@ sub delete_duplicates (\%$) {
|
|||||||
# of deny with different perms.
|
# of deny with different perms.
|
||||||
|
|
||||||
## network rules
|
## network rules
|
||||||
$deleted += delete_net_duplicates($profile->{allow}{netdomain}, $include{$incname}{allow}{netdomain});
|
$deleted += delete_net_duplicates($profile->{allow}{netdomain}, $include{$incname}{$incname}{allow}{netdomain});
|
||||||
$deleted += delete_net_duplicates($profile->{deny}{netdomain}, $include{$incname}{deny}{netdomain});
|
$deleted += delete_net_duplicates($profile->{deny}{netdomain}, $include{$incname}{$incname}{deny}{netdomain});
|
||||||
|
|
||||||
## capabilities
|
## capabilities
|
||||||
$deleted += delete_cap_duplicates($profile->{allow}{capability},
|
$deleted += delete_cap_duplicates($profile->{allow}{capability},
|
||||||
$include{$incname}{allow}{capability});
|
$include{$incname}{$incname}{allow}{capability});
|
||||||
$deleted += delete_cap_duplicates($profile->{deny}{capability},
|
$deleted += delete_cap_duplicates($profile->{deny}{capability},
|
||||||
$include{$incname}{deny}{capability});
|
$include{$incname}{$incname}{deny}{capability});
|
||||||
|
|
||||||
## paths
|
## paths
|
||||||
$deleted += delete_path_duplicates($profile, $incname, 'allow');
|
$deleted += delete_path_duplicates($profile, $incname, 'allow');
|
||||||
@@ -3577,11 +3577,11 @@ sub matchnetinclude ($$$) {
|
|||||||
while (my $name = shift @includelist) {
|
while (my $name = shift @includelist) {
|
||||||
push @checked, $name;
|
push @checked, $name;
|
||||||
return 1
|
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 this fragment includes others, check them too
|
||||||
if (keys %{ $include{$name}{include} } &&
|
if (keys %{ $include{$name}{$name}{include} } &&
|
||||||
(grep($name, @checked) == 0) ) {
|
(grep($name, @checked) == 0) ) {
|
||||||
push @includelist, keys %{ $include{$name}{include} };
|
push @includelist, keys %{ $include{$name}{$name}{include} };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3611,8 +3611,8 @@ sub matchcapincludes (\%$) {
|
|||||||
next if ($includevalid == 0);
|
next if ($includevalid == 0);
|
||||||
|
|
||||||
push @newincludes, $incname
|
push @newincludes, $incname
|
||||||
if ( defined $include{$incname}{allow}{capability}{$cap}{set} &&
|
if ( defined $include{$incname}{$incname}{allow}{capability}{$cap}{set} &&
|
||||||
$include{$incname}{allow}{capability}{$cap}{set} == 1 );
|
$include{$incname}{$incname}{allow}{capability}{$cap}{set} == 1 );
|
||||||
}
|
}
|
||||||
return @newincludes;
|
return @newincludes;
|
||||||
}
|
}
|
||||||
@@ -4223,7 +4223,7 @@ sub readprofile ($$$) {
|
|||||||
close(SDPROF);
|
close(SDPROF);
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
my $profile_data = parse_profile_data($data, $file);
|
my $profile_data = parse_profile_data($data, $file, 0);
|
||||||
if ($profile_data && $active_profile) {
|
if ($profile_data && $active_profile) {
|
||||||
attach_profile_data(\%sd, $profile_data);
|
attach_profile_data(\%sd, $profile_data);
|
||||||
attach_profile_data(\%original_sd, $profile_data);
|
attach_profile_data(\%original_sd, $profile_data);
|
||||||
@@ -4253,12 +4253,18 @@ sub attach_profile_data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub parse_profile_data {
|
sub parse_profile_data {
|
||||||
my ($data, $file) = @_;
|
my ($data, $file, $do_include) = @_;
|
||||||
|
|
||||||
|
|
||||||
my ($profile_data, $profile, $hat, $in_contained_hat, $repo_data,
|
my ($profile_data, $profile, $hat, $in_contained_hat, $repo_data,
|
||||||
@parsed_profiles);
|
@parsed_profiles);
|
||||||
my $initial_comment = "";
|
my $initial_comment = "";
|
||||||
|
|
||||||
|
if ($do_include) {
|
||||||
|
$profile = $file;
|
||||||
|
$hat = $file;
|
||||||
|
}
|
||||||
|
|
||||||
for (split(/\n/, $data)) {
|
for (split(/\n/, $data)) {
|
||||||
chomp;
|
chomp;
|
||||||
|
|
||||||
@@ -4267,6 +4273,9 @@ sub parse_profile_data {
|
|||||||
|
|
||||||
# start of a profile...
|
# start of a profile...
|
||||||
if (m/^\s*(("??\/.+?"??)|(profile\s+("??.+?"??)))\s+((flags=)?\((.+)\)\s+)*\{\s*(#.*)?$/) {
|
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
|
# if we run into the start of a profile while we're already in a
|
||||||
# profile, something's wrong...
|
# 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
|
# if we hit the end of a profile when we're not in one, something's
|
||||||
# wrong...
|
# wrong...
|
||||||
|
if ($do_include) {
|
||||||
|
die "include <$file> contains syntax errors.";
|
||||||
|
}
|
||||||
if (not $profile) {
|
if (not $profile) {
|
||||||
die sprintf(gettext('%s contains syntax errors.'), $file) . "\n";
|
die sprintf(gettext('%s contains syntax errors.'), $file) . "\n";
|
||||||
}
|
}
|
||||||
@@ -4527,6 +4539,9 @@ sub parse_profile_data {
|
|||||||
push @{$profile_data->{$profile}{$hat}{allow}{netdomain}{rule}}, $_;
|
push @{$profile_data->{$profile}{$hat}{allow}{netdomain}{rule}}, $_;
|
||||||
|
|
||||||
} elsif (m/^\s*\^(\"??.+?\"??)\s*,\s*(#.*)?$/) {
|
} elsif (m/^\s*\^(\"??.+?\"??)\s*,\s*(#.*)?$/) {
|
||||||
|
if (not $profile) {
|
||||||
|
die "$file contains syntax errors.";
|
||||||
|
}
|
||||||
# change_hat declaration - needed to change_hat to an external
|
# change_hat declaration - needed to change_hat to an external
|
||||||
# hat
|
# hat
|
||||||
$hat = $1;
|
$hat = $1;
|
||||||
@@ -4537,6 +4552,9 @@ sub parse_profile_data {
|
|||||||
unless exists($profile_data->{$profile}{$hat}{declared});
|
unless exists($profile_data->{$profile}{$hat}{declared});
|
||||||
|
|
||||||
} elsif (m/^\s*\^(\"??.+?\"??)\s+(flags=\(.+\)\s+)*\{\s*(#.*)?$/) {
|
} elsif (m/^\s*\^(\"??.+?\"??)\s+(flags=\(.+\)\s+)*\{\s*(#.*)?$/) {
|
||||||
|
if ($do_include) {
|
||||||
|
die "include <$file> contains syntax errors.";
|
||||||
|
}
|
||||||
# start of embedded hat syntax hat definition
|
# start of embedded hat syntax hat definition
|
||||||
# read in and mark as changed so that will be written out in the new
|
# read in and mark as changed so that will be written out in the new
|
||||||
# format
|
# format
|
||||||
@@ -4599,6 +4617,7 @@ sub parse_profile_data {
|
|||||||
# Cleanup : add required hats if not present in the
|
# Cleanup : add required hats if not present in the
|
||||||
# parsed profiles
|
# parsed profiles
|
||||||
#
|
#
|
||||||
|
if (not $do_include) {
|
||||||
for my $hatglob (keys %{$cfg->{required_hats}}) {
|
for my $hatglob (keys %{$cfg->{required_hats}}) {
|
||||||
for my $parsed_profile ( sort @parsed_profiles ) {
|
for my $parsed_profile ( sort @parsed_profiles ) {
|
||||||
if ($parsed_profile =~ /$hatglob/) {
|
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 we're still in a profile when we hit the end of the file, it's bad
|
||||||
if ($profile) {
|
if ($profile and not $do_include) {
|
||||||
die "Reached the end of $file while we were still inside the $profile profile.\n";
|
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->{deny}{capability}{$capname}{set};
|
||||||
return 1 if $profile->{allow}{capability}{$capname}{set};
|
return 1 if $profile->{allow}{capability}{$capname}{set};
|
||||||
for my $incname ( keys %{$profile->{include}} ) {
|
for my $incname ( keys %{$profile->{include}} ) {
|
||||||
return -1 if $include{$incname}{deny}{capability}{$capname}{set};
|
return -1 if $include{$incname}{$incname}{deny}{capability}{$capname}{set};
|
||||||
return 1 if $include{$incname}{allow}{capability}{$capname}{set};
|
return 1 if $include{$incname}{$incname}{allow}{capability}{$capname}{set};
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -5225,7 +5244,7 @@ sub profile_known_network (\%$$) {
|
|||||||
$family, $sock_type);
|
$family, $sock_type);
|
||||||
|
|
||||||
for my $incname ( keys %{$profile->{include}} ) {
|
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);
|
$family, $sock_type);
|
||||||
return 1 if netrules_access_check($include{$incname}{allow}{netdomain},
|
return 1 if netrules_access_check($include{$incname}{allow}{netdomain},
|
||||||
$family, $sock_type);
|
$family, $sock_type);
|
||||||
@@ -5292,86 +5311,17 @@ sub loadinclude {
|
|||||||
my $which = shift;
|
my $which = shift;
|
||||||
|
|
||||||
# don't bother loading it again if we already have
|
# don't bother loading it again if we already have
|
||||||
return 0 if $include{$which};
|
return 0 if $include{$which}{$which};
|
||||||
|
|
||||||
my @loadincludes = ($which);
|
my @loadincludes = ($which);
|
||||||
while (my $incfile = shift @loadincludes) {
|
while (my $incfile = shift @loadincludes) {
|
||||||
|
|
||||||
my $data = get_include_data($incfile);
|
my $data = get_include_data($incfile);
|
||||||
for (split(/\n/, $data)) {
|
my $incdata = parse_profile_data($data, $incfile, 1);
|
||||||
chomp;
|
if ($incdata) {
|
||||||
|
attach_profile_data(\%include, $incdata);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5407,20 +5357,20 @@ sub match_include_to_path ($$$) {
|
|||||||
while (my $incfile = shift @includelist) {
|
while (my $incfile = shift @includelist) {
|
||||||
my $ret = eval { loadinclude($incfile); };
|
my $ret = eval { loadinclude($incfile); };
|
||||||
if ($@) { fatal_error $@; }
|
if ($@) { fatal_error $@; }
|
||||||
my ($cm, @m) = rematchfrag($include{$incfile}, $allow, $path);
|
my ($cm, @m) = rematchfrag($include{$incfile}{$incfile}, $allow, $path);
|
||||||
if ($cm) {
|
if ($cm) {
|
||||||
$combinedmode |= $cm;
|
$combinedmode |= $cm;
|
||||||
push @matches, @m;
|
push @matches, @m;
|
||||||
}
|
}
|
||||||
|
|
||||||
# check if a literal version is in the current include fragment
|
# check if a literal version is in the current include fragment
|
||||||
if ($include{$incfile}{$allow}{path}{$path}) {
|
if ($include{$incfile}{$incfile}{$allow}{path}{$path}) {
|
||||||
$combinedmode |= $include{$incfile}{$allow}{path}{$path}{mode};
|
$combinedmode |= $include{$incfile}{$incfile}{$allow}{path}{$path}{mode};
|
||||||
}
|
}
|
||||||
|
|
||||||
# if this fragment includes others, check them too
|
# if this fragment includes others, check them too
|
||||||
if (keys %{ $include{$incfile}{include} }) {
|
if (keys %{ $include{$incfile}{$incfile}{include} }) {
|
||||||
push @includelist, keys %{ $include{$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
|
# scan the include fragments looking for matches
|
||||||
my @includelist = ($incname);
|
my @includelist = ($incname);
|
||||||
while (my $include = shift @includelist) {
|
while (my $include = shift @includelist) {
|
||||||
my ($cm, @m) = rematchfrag($include{$include}, 'allow', $path);
|
my ($cm, @m) = rematchfrag($include{$include}{$include}, 'allow', $path);
|
||||||
if ($cm) {
|
if ($cm) {
|
||||||
$combinedmode |= $cm;
|
$combinedmode |= $cm;
|
||||||
push @matches, @m;
|
push @matches, @m;
|
||||||
}
|
}
|
||||||
|
|
||||||
# check if a literal version is in the current include fragment
|
# check if a literal version is in the current include fragment
|
||||||
if ($include{$include}{allow}{path}{$path}) {
|
if ($include{$include}{$include}{allow}{path}{$path}) {
|
||||||
$combinedmode |= $include{$include}{allow}{path}{$path}{mode};
|
$combinedmode |= $include{$include}{$include}{allow}{path}{$path}{mode};
|
||||||
}
|
}
|
||||||
|
|
||||||
# if this fragment includes others, check them too
|
# if this fragment includes others, check them too
|
||||||
if (keys %{ $include{$include}{include} }) {
|
if (keys %{ $include{$include}{$include}{include} }) {
|
||||||
push @includelist, keys %{ $include{$include}{include} };
|
push @includelist, keys %{ $include{$include}{$include}{include} };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user