2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-09-01 06:45:38 +00:00

utils/aa-notify:

aa-notify would abort if it could not stat the logfile, as can happen
when using auditd and the directory perms for the logfile do not allow access
(x). Add raise_privileges() and drop_privileges() helper functions and adjust
get_logfile_size() and get_logfile_inode() to raise then drop privileges if the
logfile parent directory is not executable. Also adjust reopen_logfile() to use
these helpers.

When error checking, use '$> == ...' instead of '$> = ... or die...' since perl
always dies when raising privs in this manner even though the euid did change
(and $!, $@, $^E, and $? are all the same). Not sure why this is happening but
the '==' check should be sufficient.
This commit is contained in:
Jamie Strandboge
2011-08-17 09:48:12 -05:00
parent 0a5c4fa159
commit 94e665b3fa

View File

@@ -1,7 +1,7 @@
#!/usr/bin/perl #!/usr/bin/perl
# ------------------------------------------------------------------ # ------------------------------------------------------------------
# #
# Copyright (C) 2009-2010 Canonical Ltd. # Copyright (C) 2009-2011 Canonical Ltd.
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public # modify it under the terms of version 2 of the GNU General Public
@@ -561,42 +561,79 @@ EOF
print $s; print $s;
} }
sub raise_privileges {
my $old_euid = -1;
if ($> != $<) {
_debug("raising privileges to '$orig_euid'");
$old_euid = $>;
$> = $orig_euid;
$> == $orig_euid or die "Could not raise privileges\n";
}
return $old_euid;
}
sub drop_privileges {
my $old_euid = $_[0];
# Just exit if we didn't raise privileges
$old_euid == -1 and return;
_debug("dropping privileges to '$old_euid'");
$> = $old_euid;
$> == $old_euid or die "Could not drop privileges\n";
}
sub reopen_logfile { sub reopen_logfile {
# reopen the logfile, temporarily switching back to starting euid for # reopen the logfile, temporarily switching back to starting euid for
# file permissions. # file permissions.
close(LOGFILE); close(LOGFILE);
my $old_euid = $>; my $old_euid = raise_privileges();
my $change_euid = 0;
if ($> != $<) {
_debug("raising privileges to '$orig_euid' in reopen_logfile()");
$change_euid = 1;
$> = $orig_euid;
$> == $orig_euid or die "Could not raise privileges\n";
}
$logfile_inode = get_logfile_inode($logfile); $logfile_inode = get_logfile_inode($logfile);
$logfile_size = get_logfile_size($logfile); $logfile_size = get_logfile_size($logfile);
open (LOGFILE, "<$logfile") or die "Could not open '$logfile'\n"; open (LOGFILE, "<$logfile") or die "Could not open '$logfile'\n";
if ($change_euid) { drop_privileges($old_euid);
_debug("dropping privileges to '$old_euid' in reopen_logfile()");
$> = $old_euid;
$> == $old_euid or die "Could not drop privileges\n";
}
} }
sub get_logfile_size { sub get_logfile_size {
my $fn = $_[0]; my $fn = $_[0];
my $size; my $size;
my $dir = File::Basename::dirname($fn);
# If we can't access the file, then raise privs. This can happen when
# using auditd and /var/log/audit/ is 700.
my $old_euid = -1;
if (! -x $dir) {
$old_euid = raise_privileges();
}
defined(($size = (stat($fn))[7])) or (sleep(10) and defined(($size = (stat($fn))[7])) or die "'$fn' disappeared. Aborting\n"); defined(($size = (stat($fn))[7])) or (sleep(10) and defined(($size = (stat($fn))[7])) or die "'$fn' disappeared. Aborting\n");
drop_privileges($old_euid);
return $size; return $size;
} }
sub get_logfile_inode { sub get_logfile_inode {
my $fn = $_[0]; my $fn = $_[0];
my $inode; my $inode;
my $dir = File::Basename::dirname($fn);
# If we can't access the file, then raise privs. This can happen when
# using auditd and /var/log/audit/ is 700.
my $old_euid = -1;
if (! -x $dir) {
$old_euid = raise_privileges();
}
defined(($inode = (stat($fn))[1])) or (sleep(10) and defined(($inode = (stat($fn))[1])) or die "'$fn' disappeared. Aborting\n"); defined(($inode = (stat($fn))[1])) or (sleep(10) and defined(($inode = (stat($fn))[1])) or die "'$fn' disappeared. Aborting\n");
drop_privileges($old_euid);
return $inode; return $inode;
} }