Skip to content

Inaccurate test in SHLL-6230 #1707

@wileyhy

Description

@wileyhy

Describe the bug
The pipeline in SHLL-6230 which searches for umask input yields some
inaccurate results. It appears that the values "`umask`" and "(" were
intended to be octal umask values.

Version

  • Distribution: Fedora 43
  • Lynis version: 3.1.6

Expected behavior
I expected for the test to identify inputs for the umask command.

Output
If a system fails the test at SHLL-6230, then the following text may be printed in /var/log/lynis.log:

1221 2026-01-03 18:54:43 Performing test ID SHLL-6230 (Perform umask check for shell configurations)
1222 2026-01-03 18:54:43 Result: file /etc/bashrc exists
1223 2026-01-03 18:54:43 Result: found umask `umask` in /etc/bashrc
1224 2026-01-03 18:54:43 Result: umask `umask` can be hardened

1228 2026-01-03 18:54:43 Result: file /etc/csh.cshrc exists
1229 2026-01-03 18:54:43 Result: found umask ( in /etc/csh.cshrc
1230 2026-01-03 18:54:43 Result: umask ( can be hardened
1231 2026-01-03 18:54:43 Result: found umask 077 in /etc/csh.cshrc

1234 2026-01-03 18:54:43 Result: file /etc/profile exists
1235 2026-01-03 18:54:43 Result: found umask 077 in /etc/profile

Additional context
The command which produces this output appears on line 243 of
/usr/share/lynis/include/tests_shells.

FIND=$(${GREPBINARY} umask ${FILE} | ${SEDBINARY} 's/^[ \t]*//g' | ${SEDBINARY} 's/#.*$//' | ${GREPBINARY} -v "^$" | ${AWKBINARY} '{ print $2 }')

This pipeline:

  • (1) filters a file for the string "umask",
  • (2) removes tabs from the stream,
  • (3) removes comments from the stream,
  • (4) removes empty lines from the stream, and
  • (5) prints the second field of the resulting line of text.

On a current instance of Fedora 43, the output from command (1) of the
pipeline is:

$ grep umask /etc/bashrc /etc/bash.bashrc /etc/bash.bashrc.local /etc/csh.cshrc /etc/profile
/etc/bashrc:    # Set default umask for non-login shell only if it is set to 0
/etc/bashrc:    [ `umask` -eq 0 ] && umask 077
grep: /etc/bash.bashrc: No such file or directory
grep: /etc/bash.bashrc.local: No such file or directory
/etc/csh.cshrc:# Set default umask for non-login shell only if it is set to 0
/etc/csh.cshrc:if ( `umask` == 0 ) then
/etc/csh.cshrc:    umask 077
/etc/profile:umask 077

After processing with the commandline above, the input received by command
(5), awk, is

$ for FF in /etc/bashrc /etc/bash.bashrc /etc/bash.bashrc.local /etc/csh.cshrc /etc/profile; do printf '# file: <%s>\n' "${FF}"; grep umask "${FF}" | sed 's/^[ \t]*//g' | sed 's/#.*$//' | grep -v "^$" ; done
# file: </etc/bashrc>
[ `umask` -eq 0 ] && umask 077
# file: </etc/bash.bashrc>
grep: /etc/bash.bashrc: No such file or directory
# file: </etc/bash.bashrc.local>
grep: /etc/bash.bashrc.local: No such file or directory
# file: </etc/csh.cshrc>
if ( `umask` == 0 ) then
umask 077
# file: </etc/profile>
umask 077

The output of command (5), awk, then, is:

$ for FF in /etc/bashrc /etc/bash.bashrc /etc/bash.bashrc.local /etc/csh.cshrc /etc/profile; do printf '# file: <%s>\n' "${FF}"; grep umask "${FF}" | sed 's/^[ \t]*//g' | sed 's/#.*$//' | grep -v "^$" | awk '{ print $2}'; done
# file: </etc/bashrc>
`umask`
# file: </etc/bash.bashrc>
grep: /etc/bash.bashrc: No such file or directory
# file: </etc/bash.bashrc.local>
grep: /etc/bash.bashrc.local: No such file or directory
# file: </etc/csh.cshrc>
(
077
# file: </etc/profile>
077

As a suggested resolution, the following awk command prints octal umask inputs on Fedora 43 using
gawk (v.5.3.2), gawk -P, mawk (v.1.3.4 20250131), and nawk (v.20250116).

awk '{
        # If there is a comment in the current record, then go to the next record
        if (/#/) {
                next
        }
        # Split record $0 using the default field separator and create array "arr" with the resulting fields 
        split($0, arr)
        # For each element of the array "arr"...
        for (xx in arr) {
        	# If the current element is equivalent to the string "umask", and if the next element consists 
        	# entirely of integers, and is three to five characters in length, then print the next element. 
                if (arr[xx] == "umask" && arr[xx + 1] ~ /^[0-9]{3,5}$/ ) {
                        print arr[xx + 1]
                }
        }
}' "${FF}"
$ bash ./bug_lynis.sh 
# file: /etc/bashrc
077
# file: /etc/bash.bashrc
gawk: fatal: cannot open file `/etc/bash.bashrc' for reading: No such file or directory
# file: /etc/bash.bashrc.local
gawk: fatal: cannot open file `/etc/bash.bashrc.local' for reading: No such file or directory
# file: /etc/csh.cshrc
077
# file: /etc/profile
077

Compacted and translated into local style:

FIND=$( ${AWKBINARY} '{ if (/#/) { next }; split($0, arr); for (xx in arr) { if (arr[xx] == "umask" && arr[xx + 1] ~ /^[0-9]{3,5}$/ ) { print arr[xx + 1] } } }' "${FILE}" )

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions