Download raw body.
Watch relink files for changes for setuid files in security(8)
On Tue, Jun 04, 2024 at 06:48:12PM -0700, Andrew Hewus Fresh wrote:
> Someone (florian@) noticed that security(8) complains every time about
> ssh-agent changing any time you reboot.
Another thing we can do is monitor the relink file instead of the
setuid file itself.
It takes a bit of refactoring, so probably not worth it. Just thought
it worthwhile to try it.
Thoughts? Comments?
Index: security
===================================================================
RCS file: /cvs/src/libexec/security/security,v
retrieving revision 1.43
diff -u -p -r1.43 security
--- security 9 Jun 2024 18:31:17 -0000 1.43
+++ security 9 Jun 2024 22:04:15 -0000
@@ -30,7 +30,7 @@ require File::Find;
use constant {
BACKUP_DIR => '/var/backups/',
- RELINK_DIR => '/usr/share/relink/',
+ RELINK_DIR => '/usr/share/relink',
};
$ENV{PATH} = '/bin:/usr/bin:/sbin:/usr/sbin';
@@ -529,6 +529,27 @@ sub strmode {
. (strmode_x $mode, S_IXOTH, S_ISVTX);
}
+sub _lstat_special_file {
+ my ($filename) = @_;
+
+ my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
+ $atime, $mtime, $ctime, $blksize, $blocks) = lstat $filename;
+
+ my %file = (
+ dev => $dev,
+ mode => $mode,
+ nlink => $nlink,
+ uid => $uid,
+ gid => $gid,
+ rdev => $rdev,
+ size => $size,
+ );
+
+ @file{qw(wday mon day time year)} = split ' ', localtime $mtime;
+
+ return \%file;
+}
+
sub find_special_files {
my (%skip, @fs);
@@ -559,11 +580,11 @@ sub find_special_files {
return;
}
- my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
- $atime, $mtime, $ctime, $blksize, $blocks) = lstat;
- if (defined $dev) {
+ my $file = _lstat_special_file($_);
+
+ if (defined $file->{dev}) {
no warnings 'once';
- if ($dev != $File::Find::topdev) {
+ if ($file->{dev} != $File::Find::topdev) {
$File::Find::prune = 1;
return;
}
@@ -573,10 +594,17 @@ sub find_special_files {
}
# SUID/SGID files
- my $file = {};
- if (-f _ && $mode & (S_ISUID | S_ISGID)) {
- return if -e RELINK_DIR . $_;
- $setuid_files->{$File::Find::name} = $file;
+ if (-f _ && $file->{mode} & (S_ISUID | S_ISGID)) {
+ if ( -e RELINK_DIR . $_ ) {
+ File::Find::find({no_chdir => 1, wanted => sub {
+ my $f = _lstat_special_file($_);
+ $setuid_files->{$File::Find::name}
+ = $f if -f _;
+ }}, RELINK_DIR . $_ );
+ }
+ else {
+ $setuid_files->{$File::Find::name} = $file;
+ }
$uudecode_is_setuid = 1
if basename($_) eq 'uudecode';
}
@@ -584,22 +612,25 @@ sub find_special_files {
# Special Files
elsif (!-d _ && !-f _ && !-l _ && !-S _ && !-p _ ) {
$device_files->{$File::Find::name} = $file;
- $file->{major} = (($rdev >> 8) & 0xff) . ',';
- $file->{minor} = (($rdev >> 8) & 0xffff00) |
- ($rdev & 0xff);
+ $file->{major} = (($file->{rdev} >> 8) & 0xff) . ',';
+ $file->{minor} = (($file->{rdev} >> 8) & 0xffff00) |
+ ($file->{rdev} & 0xff);
} else {
return;
}
- $file->{mode} = $mode;
- $file->{strmode} = strmode $mode;
- $file->{nlink} = $nlink;
- $file->{user} = (getpwuid $uid)[0] // $uid;
- $file->{group} = (getgrgid $gid)[0] // $gid;
- $file->{size} = $size;
- @$file{qw(wday mon day time year)} =
- split ' ', localtime $mtime;
}}, @fs);
+
+ my %getpw;
+ foreach my $files ($setuid_files, $device_files) {
+ foreach my $file (values %$files) {
+ $file->{strmode} = strmode $file->{mode};
+ $file->{user} = $getpw{uid}{ $file->{uid} }
+ //= (getpwuid $file->{uid})[0] // $$file->{uid};
+ $file->{group} = $getpw{gid}{ $file->{gid} }
+ //= (getgrgid $file->{gid})[0] // $file->{gid};
+ }
+ }
nag $uudecode_is_setuid, 'Uudecode is setuid.';
return $setuid_files, $device_files;
Watch relink files for changes for setuid files in security(8)