“Ensure core dumps are restricted” is a CIS benchmark check that fails when a Linux host still lets processes, including setuid programs, write their memory to disk after a crash. To fix it, add * hard core 0 to limits.conf, set fs.suid_dumpable = 0 in /etc/sysctl.d/, and, if systemd-coredump is installed, set Storage=none and ProcessSizeMax=0.
Each setting closes a different path, and each can be quietly undone: the limits file only covers login sessions, and the packages behind systemd-coredump and Apport can put fs.suid_dumpable back to 2 at every boot.
What the scanner is actually detecting
This finding comes from a Tenable compliance scan that runs a CIS Linux benchmark audit file over an authenticated SSH session. It is a configuration check that reports PASSED or FAILED, not a vulnerability plugin, and there is no CVE behind it. Depending on the audit version, it evaluates the limits files, the sysctl files, the live kernel value and, on systemd hosts, the systemd-coredump configuration.
The exact title depends on the benchmark and its version. Older Tenable audits split the one CIS recommendation into several items and append a suffix naming the part that was evaluated. Newer benchmarks for systemd-based distributions break the systemd-coredump part out into separate recommendations:
| Tenable audit (CIS benchmark) | Item title |
|---|---|
| CIS Debian Linux 12 v1.0.1 L1 Server | 1.5.3 Ensure core dumps are restricted |
| CIS Red Hat EL8 Workstation L1 v1.0.1 | 1.6.1 Ensure core dumps are restricted – limits.conf limits.d |
| CIS Red Hat EL8 Server L1 v1.0.1 | 1.6.1 Ensure core dumps are restricted – sysctl.conf sysctl.d |
| CIS Red Hat EL7 Server L1 v3.0.1 | 1.6.1 Ensure core dumps are restricted – systemd-coredump Storage |
| CIS Red Hat EL7 STIG v2.0.0 L1 Server | 1.5.1 Ensure core dumps are restricted – sysctl, and – systemd-coredump ProcessSizeMax |
| CIS Ubuntu 18.04 LXD Host v1.0.0 L1 Workstation | 1.6.4 Ensure core dumps are restricted – sysctl config |
| CIS CentOS Linux 8 Server v2.0.0 L1, CIS Red Hat EL8 Workstation v2.0.0 L1 | 1.5.1 Ensure core dump storage is disabled |
| CIS Rocky Linux 8 v1.0.0 L1 Server | 1.5.2 Ensure core dump backtraces are disabled |
One host can therefore show two or three failures that all trace back to this recommendation. Search your report by title rather than item number, because numbering shifts between versions.
Real-world risk, stated honestly
A core file is a copy of a process’s memory at the moment it crashed, so passwords, private keys, session tokens or decrypted data in memory at that point can end up on disk. That is the whole CIS rationale.
- Setuid programs are the main concern. The kernel documentation describes three values for fs.suid_dumpable. 0 is the default: a process that changed privilege level is not dumped. 1 is a debug mode in which such processes dump core owned by the current user with no security applied. 2 (“suidsafe”) dumps them anyway, but only to a pipe handler or an absolute path.
- Stored dumps pile up. With systemd-coredump’s default Storage=external, cores are kept in /var/lib/systemd/coredump/, where they can be swept into backups, support bundles or log shipping.
- Scope. This is local information disclosure hardening. Nothing here is remotely exploitable: someone needs a crash, and read access to the resulting dump, before any data leaks. It is low severity, but the fix is cheap.
How to confirm it on the host
Check each of the three parts separately. Run these from a fresh SSH session, because limits are applied at login:
# 1. Hard core limit (expect 0) and the lines that set it
ulimit -Hc
grep -Hs '^[^#]*core' /etc/security/limits.conf /etc/security/limits.d/*
# 2. Live value (expect 0) and every sysctl file that sets it
sysctl fs.suid_dumpable
grep -Hs 'suid_dumpable' /etc/sysctl.conf /etc/sysctl.d/*.conf /run/sysctl.d/*.conf
/usr/local/lib/sysctl.d/*.conf /usr/lib/sysctl.d/*.conf /lib/sysctl.d/*.conf
# 3. Who receives core dumps, and the effective systemd-coredump settings
sysctl kernel.core_pattern
command -v coredumpctl && systemd-analyze cat-config systemd/coredump.conf
systemctl is-active apport.service
On older systemd releases without the cat-config verb, read /etc/systemd/coredump.conf and any files in /etc/systemd/coredump.conf.d/ directly.
Read the core_pattern value first. A pipe to systemd-coredump means systemd handles crashes, a pipe to /usr/share/apport/apport means Apport does (common on Ubuntu), and the plain kernel default core means the kernel writes a file into the crashing process’s working directory. If the grep in step 2 shows /usr/lib/sysctl.d/50-coredump.conf setting fs.suid_dumpable=2, that is systemd-coredump’s own file, shipped since systemd 246, and your setting has to sort after it.
How to fix it
Step 1: set a hard core limit of 0
echo '* hard core 0' | sudo tee /etc/security/limits.d/60-coredump.conf
A hard limit cannot be raised by the user, unlike a soft limit. pam_limits reads limits.conf and then every *.conf file in limits.d, and user-specific lines take priority over the * default. Review any line such as appuser hard core unlimited: the audit may still pass, but that user can dump core.
Step 2: set fs.suid_dumpable to 0, persistently and live
printf '%sn' 'fs.suid_dumpable = 0' | sudo tee /etc/sysctl.d/60-fs_sysctl.conf
sudo sysctl -w fs.suid_dumpable=0
The file name matters. sysctl.d files must end in .conf, and when two files set the same key, the file whose name sorts last wins, regardless of directory. A name starting with 60 sorts after systemd’s 50-coredump.conf. Also remove any fs.suid_dumpable line in /etc/sysctl.conf, which sysctl –system reads last. Run sudo sysctl –system and check that the final value it applies is 0.
Step 3: disable systemd-coredump storage (if installed)
Edit /etc/systemd/coredump.conf (create it if it does not exist) so the [Coredump] section contains:
[Coredump]
Storage=none
ProcessSizeMax=0
Then run sudo systemctl daemon-reload as the CIS remediation specifies. According to coredump.conf(5), this combination disables all core dump handling except a log entry. Drop-ins in /etc/systemd/coredump.conf.d/ override the main file, so make sure none of them sets Storage or ProcessSizeMax back.
Step 4: Ubuntu and Debian hosts running Apport
Every time apport.service starts, it writes its own core_pattern and sets fs.suid_dumpable to 2, which overrides your sysctl file after each boot. CIS covers this with a separate item, “Ensure Automatic Error Reporting is not enabled”. Its remediation is to set enabled=0 in /etc/default/apport and then run:
sudo systemctl stop apport.service
sudo systemctl --now disable apport.service
Removing the package with apt purge apport also works. Stopping Apport resets fs.suid_dumpable to 0 and core_pattern back to core.
How to verify the fix and rescan
- Reboot once if you can. Boot is when 50-coredump.conf and Apport reapply their values, so a check made before a reboot can pass and then fail on the next scan.
- From a new SSH session, confirm ulimit -Hc prints 0 and sysctl fs.suid_dumpable prints 0.
- Run systemd-analyze cat-config systemd/coredump.conf and confirm the last Storage and ProcessSizeMax values shown are none and 0.
- Optionally, force a harmless crash as a normal user and confirm nothing is stored:
sleep 300 & kill -SEGV $! coredumpctl list ls /var/lib/systemd/coredump/If the crash is listed, its COREFILE column should read none, and no new file should appear in the directory.
- Rerun the same compliance scan with the same audit file and credentials. If the scan cannot read /etc/security or /etc/systemd, see our guide to setting up SSH and sudo credentials for Linux authenticated scans.
What can break and how to roll back
Nothing stops running, but you lose post-mortem data that developers, vendor support and crash reporters such as Apport rely on.
- Services behave differently from users. systemd-system.conf(5) notes that PID 1 sets RLIMIT_CORE to infinity, and services inherit that, not limits.conf. Storage=none is what actually stops their cores being stored on systemd-coredump hosts.
- Scoped exceptions. CIS suggests per-group limits if some cores are genuinely needed. To capture a core from one service during an incident, temporarily set Storage=external and raise ProcessSizeMax, then put both back; the service’s own core limit is already unlimited unless LimitCORE= or DefaultLimitCORE= says otherwise.
- Rollback. Delete /etc/security/limits.d/60-coredump.conf (applies from the next login), delete /etc/sysctl.d/60-fs_sysctl.conf and run sudo sysctl –system, restore the previous coredump.conf, and re-enable Apport with sudo systemctl enable –now apport.service if you used it. No reboot is required.
Common false positive reasons
- Half-applied fix. Running only sysctl -w passes the live check but fails the file check; writing only the file does the opposite until the next boot. Both look like false positives but are real gaps.
- Wrong file name. A sysctl.d file without the .conf extension is ignored, and so is a limits.d file that does not match *.conf.
- Setting only in a drop-in. The remediation text in the older audits points at /etc/systemd/coredump.conf itself, so a value that lives only in coredump.conf.d may be effective but still reported as failed. Put the lines in the main file.
- Different syntax. A line such as * – core 0 sets both limits, but it is not the form CIS documents and may not match what the check looks for. Use * hard core 0.
- systemd-coredump not installed. The systemd part only applies when the package is present. If the item fails anyway, adding the two lines is harmless.
FAQ
Is * hard core 0 enough on its own?
No. It only applies to PAM login sessions. Services inherit an unlimited limit from systemd, and core(5) notes that the kernel does not enforce RLIMIT_CORE when core dumps are piped to a handler, which leaves the decision to that handler. That is why CIS also requires fs.suid_dumpable and the systemd-coredump settings.
Why does fs.suid_dumpable go back to 2 after a reboot?
Usually because systemd-coredump’s /usr/lib/sysctl.d/50-coredump.conf sorts after your file, or because apport.service set it at boot. Use a file name that sorts after 50 and disable Apport.
Does Storage=none stop crashes from being logged?
No. With Storage=none and ProcessSizeMax=0, systemd-coredump still writes a log entry to the journal. It just does not keep the core or process it for a backtrace.
Can I set fs.suid_dumpable to 2 instead?
Not if you want the check to pass. CIS requires 0. Value 2 still dumps privileged processes, just to a pipe or an absolute path.
Tracking this finding across many hosts
On a large Linux estate, the hard part is spotting the hosts where Apport or a sysctl file put the value back after a reboot. If you use SITEY, you can upload the .nessus export from the compliance scan and have its AI draft a host-specific remediation script. The script runs only after a human approves it, its agents deploy it on Linux endpoints, and a re-test then verifies the finding is closed.