2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-31 14:25:52 +00:00

This change was contributed by Mathias Gug <mathias.gug@ubuntu.com>

This patch improves the information reported by then apparmor_status
script. It gives more detailed information about loaded profiles and
their mode, running processes and profiles applied to them.

(I slightly modified the code to refer to the term unconfined instead of
unstrained as well fixing some minor formatting issues.)
This commit is contained in:
Steve Beattie
2007-05-31 05:43:16 +00:00
parent 42ec04076f
commit 2493d03f93

View File

@@ -13,6 +13,7 @@
use strict;
use Getopt::Long;
use Cwd 'abs_path';
my $confdir = "/etc/apparmor";
my $sd_mountpoint;
@@ -73,44 +74,44 @@ sub find_subdomainfs() {
return $sd_mountpoint;
}
sub count_profiles {
sub get_profiles {
my $mountpoint = shift;
my $profiles = 0;
my $enforced = 0;
my $complain = 0;
my %profiles = ();
if (open(PROFILES, "$mountpoint/profiles")) {
while(<PROFILES>) {
$profiles++;
$enforced++ if m/\(enforce\)$/;
$complain++ if m/\(complain\)$/;
$profiles{$1} = $2 if m/^([^\(]+)\s+\((\w+)\)$/;
}
close(PROFILES);
}
return ($profiles, $enforced, $complain);
return (%profiles);
}
sub count_processes {
my $processes = 0;
my $confined = 0;
my $enforced = 0;
my $complain = 0;
sub get_processes {
my %profiles = @_;
my %processes = ();
if (opendir(PROC, "/proc")) {
my $file;
while (defined($file = readdir(PROC))) {
if ($file =~ m/^\d+/ && open(CURRENT, "/proc/$file/attr/current")) {
while (<CURRENT>) {
$processes++;
$confined++ if not m/^uncon(stra|f)ined$/;
$enforced++ if m/\(enforce\)$/;
$complain++ if m/\(complain\)$/;
}
close(CURRENT);
if ($file =~ m/^\d+/) {
if (open(CURRENT, "/proc/$file/attr/current")) {
while (<CURRENT>) {
if (m/^([^\(]+)\s+\((\w+)\)$/) {
$processes{$file}{'profile'} = $1;
$processes{$file}{'mode'} = $2;
} elsif (grep(abs_path("/proc/$file/exe") eq $_ , keys(%profiles))) {
# keep only unconfined processes that have a profile defined
$processes{$file}{'profile'} = abs_path("/proc/$file/exe");
$processes{$file}{'mode'} = 'unconfined';
}
}
close(CURRENT);
}
}
}
closedir(PROC);
}
return ($processes, $confined, $enforced, $complain);
return (%processes);
}
my $is_loaded = is_subdomain_loaded();
@@ -135,49 +136,83 @@ if (! -r "$sd_mountpoint/profiles") {
#print "subdomainfs is at $sd_mountpoint.\n" if $verbose;
my $processes;
my $profiles;
my $enforced;
my $complain;
# processes is a hash table :
# * keys : processes pid
# * values : hash containing information about the running process:
# * 'profile' : name of the profile applied to the running process
# * 'mode' : mode of the profile applied to the running process
my %processes = ();
my %enforced_processes = ();
my %complain_processes = ();
my %unconfined_processes = ();
($profiles, $enforced, $complain) = count_profiles($sd_mountpoint);
# profiles is a hash table :
# * keys : profile name
# * value : profile mode
my %profiles;
my @enforced_profiles = ();
my @complain_profiles = ();
%profiles = get_profiles($sd_mountpoint);
@enforced_profiles = grep { $profiles{$_} eq 'enforce' } keys %profiles;
@complain_profiles = grep { $profiles{$_} eq 'complain' } keys %profiles;
# we consider the case where no profiles are loaded to be "disabled" as well
my $rc = ($profiles == 0) ? 2 : 0;
my $rc = (keys(%profiles) == 0) ? 2 : 0;
if ($check_enabled) {
exit $rc;
}
if ($count_profiled) {
print "$profiles\n";
print scalar(keys(%profiles)). "\n";
exit $rc;
}
if ($count_enforced) {
print "$enforced\n";
print $#enforced_profiles + 1 . "\n";
exit $rc;
}
if ($count_complain) {
print "$complain\n";
print $#complain_profiles + 1 . "\n";
exit $rc;
}
if ($verbose) {
print "$profiles profiles are loaded.\n";
print "$enforced profiles are in enforce mode.\n";
print "$complain profiles are in complain mode.\n";
print keys(%profiles) . " profiles are loaded.\n";
print $#enforced_profiles + 1 . " profiles are in enforce mode.\n";
for (@enforced_profiles) {
print " " . $_ . "\n";
}
print $#complain_profiles + 1 . " profiles are in complain mode.\n";
for (@complain_profiles) {
print " " . $_ . "\n";
}
}
($processes, $profiles, $enforced, $complain) = count_processes();
%processes = get_processes(%profiles);
if ($verbose) {
print "Out of $processes processes running:\n";
print "$profiles processes have profiles defined.\n";
print "$enforced processes have profiles in enforce mode.\n";
print "$complain processes have profiles in complain mode.\n";
for (keys(%processes)) {
$enforced_processes{$_} = $processes{$_} if $processes{$_}{'mode'} eq 'enforce';
$complain_processes{$_} = $processes{$_} if $processes{$_}{'mode'} eq 'complain';
# some early code uses unconfined instead of unconfined.
$unconfined_processes{$_} = $processes{$_} if $processes{$_}{'mode'} =~ /uncon(fi|strai)ned/;
}
print keys(%processes) . " processes have profiles defined.\n";
print keys(%enforced_processes) . " processes are in enforce mode :\n";
for (keys(%enforced_processes)) {
print " " . $enforced_processes{$_}{'profile'} . " ($_) \n";
}
print keys(%complain_processes) . " processes are in complain mode.\n";
for (keys(%complain_processes)) {
print " " . $complain_processes{$_}{'profile'} . " ($_) \n";
}
print keys(%unconfined_processes) . " processes are unconfined but have a profile defined.\n";
for (keys(%unconfined_processes)) {
print " " . $unconfined_processes{$_}{'profile'} . " ($_) \n";
}
}
exit $rc;