Hi,

Doug Moss wrote on Mon, May 04, 2020 at 03:01:43PM +0000:

> For OpenBSD 6.6, amd64
> in the daily script to check security:
> /usr/libexec/security
> 
> at line 248 for checking if the umask is set:
>  my @list = qw(/etc/profile /root/.profile);
> 
> shouldn't that be instead:
>  my @list = qw(/.profile /root/.profile);
> 
> I think /etc/profile does not exist, and /.profile is the default one.

So, here is a diff to also check /.profile.

Some remarks:

 1. It is both more robust and simpler to also check existence
    and non-emptiness of startup files in check_umask(), such
    that check_sh() need not check that at multiple places.

 2. I'm not trying to sneak unrelated changes into the diff:
    the change in check_root_path() is related.  With the diff,
    we are testing more files.  If we don't say which file an
    issue is located in, we may confuse the sysadmin.

 3. The PATH and ENV checks in check_sh() have to be done in just
    the same way as they are now, for each of the files in turn.
    But the umask check is different.  It is not sufficient that
    the umask is set in /root/.profile *or* in /.profile because
    sometimes one gets executed, sometimes the other, so it should
    be set in both, or in /etc/profile.

 4. The order of the conditions in
      nag !(check_umask($filename) || $etcumask)
    may seem surprising at first.  But it is intentional that
    check_umask() is not short-circuited but always called, even
    if we already know that $etcumask is set, because in addition
    to catching situations where the umask is not set at all,
    we also want to catch situations where it is set to dubious
    values, even when it is set at multiple places.

 5. The function check_csh() suffers from essentially the same issue
    as check_sh(): it fails to consider /.cshrc.  But the situation
    over there is even worse: right now, check_csh() considers the
    umask set when it is set in just one of the four files.  If
    that is merely one of the "login" files, shells that are not
    login shells still won't have a umask.  The solution may be to
    check the value of the umask in all of the five files where it
    is set, but to require that it be set at least at these places:
    (/root/.cshrc AND /.cshrc) OR /etc/csh.cshrc, removing the
    "login" files from the "is it set at all" check.
    But this diff is already large enough.  Before deciding whether
    to tackle check_csh(), too, i'd first like some feedback on the
    diff shown below.

I would be more or less comfortable with committing the diff shown
below after unlock, but i worry a bit that committing it now may
not be good timing.

What do you think:  Do we want this at all?  Do we want it now?
And should i prepare another diff for check_csh()?

Yours,
  Ingo


Index: security
===================================================================
RCS file: /cvs/src/libexec/security/security,v
retrieving revision 1.38
diff -U4 -p -r1.38 security
--- security    27 Dec 2016 09:17:52 -0000      1.38
+++ security    5 May 2020 11:14:32 -0000
@@ -185,8 +185,9 @@ sub check_group {
 }
 
 sub check_umask {
        my ($filename) = @_;
+       -s $filename || return 0;
        nag !(open my $fh, '<', $filename), "open: $filename: $!" and return;
        my $umaskset;
        while (<$fh>) {
                next unless /^\s*umask\s+([0-7]+)/;
@@ -209,9 +210,11 @@ sub check_root_path {
        nag !(defined $path && $path =~ s/^PATH=[:\s]*//),
            "Failed to find PATH in $filename."
            and return;
        foreach my $dir (split /[:\s]+/, $path) {
-               nag $dir eq '.', "The root path includes ." and next;
+               nag $dir eq '.',
+                   "The root path in $filename includes ."
+                   and next;
                next unless -d $dir;
                my $mode = (stat(_))[2];
                nag $mode & S_IWGRP,
                    "Root path directory $dir is group writable.";
@@ -244,34 +247,35 @@ sub check_csh {
            "\nRoot csh startup files do not set the umask.";
 }
 
 sub check_sh {
-       my @list = qw(/etc/profile /root/.profile);
-       $check_title = "Checking root sh paths, umask values:\n@list";
+       my @list = qw(/etc/profile /root/.profile /.profile);
+       $check_title = "Checking root sh paths:\n@list";
 
        my @env_path;
-       my $umaskset = 0;
        foreach my $filename (@list) {
                next unless -s $filename;
-               $umaskset ||= check_umask($filename);
-
                nag !(open my $fh, '-|', qw(/bin/sh -c),
                        ". $filename; echo ENV=\$ENV; echo PATH=\$PATH"),
                    "cannot spawn /bin/sh: $!"
                    and next;
                my @output = <$fh>;
                close_or_nag $fh, "sh $filename" or next;
                chomp @output;
                check_root_path pop @output, $filename;
-
                my $env = pop @output;
                nag !(defined $env && $env =~ /^ENV=\s*(\S*)/),
                    "Failed to find ENV in $filename."
                    and next;
                push @env_path, $1 if $1 ne '';
        }
-       nag !$umaskset,
-           "\nRoot sh startup files do not set the umask.";
+       $check_title = "Checking root sh umask values:\n@list";
+       my $etcfile = shift @list;
+       my $etcumask = check_umask($etcfile);
+       foreach my $filename (@list) {
+               nag !(check_umask($filename) || $etcumask),
+                   "Neither $etcfile nor $filename sets the umask.";
+       }
        return @env_path;
 }
 
 sub check_ksh {

Reply via email to