Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
kernel-hardening-checker
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fact-depend
kernel-hardening-checker
Commits
dc68441b
Commit
dc68441b
authored
Jul 09, 2023
by
Alexander Popov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add the basic infrastructure for checking sysctl
Refers to #65
parent
d50ea2d4
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
35 additions
and
7 deletions
+35
-7
__init__.py
kconfig_hardened_check/__init__.py
+29
-4
checks.py
kconfig_hardened_check/checks.py
+6
-3
No files found.
kconfig_hardened_check/__init__.py
View file @
dc68441b
...
...
@@ -17,7 +17,7 @@ from collections import OrderedDict
import
re
import
json
from
.__about__
import
__version__
from
.checks
import
add_kconfig_checks
,
add_cmdline_checks
,
normalize_cmdline_options
from
.checks
import
add_kconfig_checks
,
add_cmdline_checks
,
normalize_cmdline_options
,
add_sysctl_checks
from
.engine
import
populate_with_data
,
perform_checks
,
override_expected_value
...
...
@@ -197,6 +197,10 @@ def parse_cmdline_file(parsed_options, fname):
parsed_options
[
name
]
=
value
def
parse_sysctl_file
(
parsed_options
,
fname
):
print
(
'parse_sysctl_file: TODO'
)
def
main
():
# Report modes:
# * verbose mode for
...
...
@@ -214,11 +218,14 @@ def main():
help
=
'check the security hardening options in the kernel Kconfig file (also supports *.gz files)'
)
parser
.
add_argument
(
'-l'
,
'--cmdline'
,
help
=
'check the security hardening options in the kernel cmdline file (contents of /proc/cmdline)'
)
# parser.add_argument('-s', '--sysctl',
# help='check the security hardening options in the sysctl output file (`sudo sysctl -a > file`)')
parser
.
add_argument
(
'-p'
,
'--print'
,
choices
=
supported_archs
,
help
=
'print the security hardening recommendations for the selected microarchitecture'
)
parser
.
add_argument
(
'-g'
,
'--generate'
,
choices
=
supported_archs
,
help
=
'generate a Kconfig fragment with the security hardening options for the selected microarchitecture'
)
args
=
parser
.
parse_args
()
args
.
sysctl
=
None
# FIXME
mode
=
None
if
args
.
mode
:
...
...
@@ -239,6 +246,8 @@ def main():
print
(
f
'[+] Kconfig file to check: {args.config}'
)
if
args
.
cmdline
:
print
(
f
'[+] Kernel cmdline file to check: {args.cmdline}'
)
if
args
.
sysctl
:
print
(
f
'[+] Kernel sysctl output file to check: {args.sysctl}'
)
arch
,
msg
=
detect_arch
(
args
.
config
,
supported_archs
)
if
arch
is
None
:
...
...
@@ -266,6 +275,10 @@ def main():
# add relevant cmdline checks to the checklist
add_cmdline_checks
(
config_checklist
,
arch
)
if
args
.
sysctl
:
# add relevant sysctl checks to the checklist
add_sysctl_checks
(
config_checklist
,
arch
)
# populate the checklist with the parsed Kconfig data
parsed_kconfig_options
=
OrderedDict
()
parse_kconfig_file
(
parsed_kconfig_options
,
args
.
config
)
...
...
@@ -280,6 +293,12 @@ def main():
parse_cmdline_file
(
parsed_cmdline_options
,
args
.
cmdline
)
populate_with_data
(
config_checklist
,
parsed_cmdline_options
,
'cmdline'
)
if
args
.
sysctl
:
# populate the checklist with the parsed sysctl data
parsed_sysctl_options
=
OrderedDict
()
parse_sysctl_file
(
parsed_sysctl_options
,
args
.
sysctl
)
populate_with_data
(
config_checklist
,
parsed_sysctl_options
,
'sysctl'
)
# hackish refinement of the CONFIG_ARCH_MMAP_RND_BITS check
mmap_rnd_bits_max
=
parsed_kconfig_options
.
get
(
'CONFIG_ARCH_MMAP_RND_BITS_MAX'
,
None
)
if
mmap_rnd_bits_max
:
...
...
@@ -293,6 +312,8 @@ def main():
all_parsed_options
=
parsed_kconfig_options
# assignment does not copy
if
args
.
cmdline
:
all_parsed_options
.
update
(
parsed_cmdline_options
)
if
args
.
sysctl
:
all_parsed_options
.
update
(
parsed_sysctl_options
)
print_unknown_options
(
config_checklist
,
all_parsed_options
)
# finally print the results
...
...
@@ -300,22 +321,26 @@ def main():
sys
.
exit
(
0
)
elif
args
.
cmdline
:
sys
.
exit
(
'[!] ERROR: checking cmdline doesn
\'
t work without checking Kconfig'
)
sys
.
exit
(
'[!] ERROR: checking cmdline depends on checking Kconfig'
)
elif
args
.
sysctl
:
# TODO: sysctl check should also work separately
sys
.
exit
(
'[!] ERROR: checking sysctl depends on checking Kconfig'
)
if
args
.
print
:
assert
(
args
.
config
is
None
and
args
.
cmdline
is
None
),
'unexpected args'
assert
(
args
.
config
is
None
and
args
.
cmdline
is
None
and
args
.
sysctl
is
None
),
'unexpected args'
if
mode
and
mode
not
in
(
'verbose'
,
'json'
):
sys
.
exit
(
f
'[!] ERROR: wrong mode "{mode}" for --print'
)
arch
=
args
.
print
add_kconfig_checks
(
config_checklist
,
arch
)
add_cmdline_checks
(
config_checklist
,
arch
)
add_sysctl_checks
(
config_checklist
,
arch
)
if
mode
!=
'json'
:
print
(
f
'[+] Printing kernel security hardening options for {arch}...'
)
print_checklist
(
mode
,
config_checklist
,
False
)
sys
.
exit
(
0
)
if
args
.
generate
:
assert
(
args
.
config
is
None
and
args
.
cmdline
is
None
),
'unexpected args'
assert
(
args
.
config
is
None
and
args
.
cmdline
is
None
and
args
.
sysctl
is
None
),
'unexpected args'
if
mode
:
sys
.
exit
(
f
'[!] ERROR: wrong mode "{mode}" for --generate'
)
arch
=
args
.
generate
...
...
kconfig_hardened_check/checks.py
View file @
dc68441b
...
...
@@ -11,7 +11,7 @@ This module contains knowledge for checks.
# pylint: disable=missing-function-docstring,line-too-long,invalid-name
# pylint: disable=too-many-branches,too-many-statements
from
.engine
import
KconfigCheck
,
CmdlineCheck
,
VersionCheck
,
OR
,
AND
from
.engine
import
KconfigCheck
,
CmdlineCheck
,
SysctlCheck
,
VersionCheck
,
OR
,
AND
def
add_kconfig_checks
(
l
,
arch
):
...
...
@@ -574,10 +574,9 @@ def normalize_cmdline_options(option, value):
return
value
#
def add_sysctl_checks(l, arch):
def
add_sysctl_checks
(
l
,
arch
):
# TODO: draft of security hardening sysctls:
# kernel.kptr_restrict=2 (or 1?)
# kernel.dmesg_restrict=1 (also see the kconfig option)
# kernel.perf_event_paranoid=2 (or 3 with a custom patch, see https://lwn.net/Articles/696216/)
# kernel.kexec_load_disabled=1
# kernel.yama.ptrace_scope=3
...
...
@@ -605,3 +604,7 @@ def normalize_cmdline_options(option, value):
# kernel.oops_limit (think about a proper value)
# kernel.warn_limit (think about a proper value)
# net.ipv4.tcp_syncookies=1 (?)
#
# Calling the SysctlCheck class constructor:
# SysctlCheck(reason, decision, name, expected)
l
+=
[
SysctlCheck
(
'self_protection'
,
'kspp'
,
'kernel.dmesg_restrict'
,
'1'
)]
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment