A flaw was found in systemd. Attacker controlled alloca() in function unit_name_path_escape() leads to a crash in systemd and ultimately a kernel panic. Systemd parses the content of /proc/self/mountinfo and each mountpoint is passed to mount_setup_unit(), which calls unit_name_path_escape() underneath to duplicate the string through alloca(). A local attacker who is able to mount a filesystem on a very long path can crash systemd and the whole system. Upstream PR: https://github.com/systemd/systemd/pull/20256 Upstream commit: https://github.com/systemd/systemd/pull/20256/commits/441e0115646d54f080e5c3bb0ba477c892861ab9
systemd as shipped in RHEL7 is not affected by this flaw because `unit_name_path_escape()` uses the heap instead of the stack. ``` char *unit_name_path_escape(const char *f) { _cleanup_free_ char *p = NULL; assert(f); p = strdup(f); if (!p) return NULL; path_kill_slashes(p); if (STR_IN_SET(p, "/", "")) return strdup("-"); return unit_name_escape(p[0] == '/' ? p + 1 : p); } ```
This vulnerability was likely introduced in systemd v220 with the following commit which replaced a strdup() in the heap with a strdupa() on the stack. https://github.com/systemd/systemd/commit/7410616cd9dbbec97cf98d75324da5cda2b2f7a2
Function unit_name_path_escape() uses strdupa to duplicate the path string passed as argument. strdupa is like strdup but it allocates the buffer on the stack with `alloca()`. If the size passed to `alloca()` is bigger than the available stack, the program writes to the wrong memory region (e.g. unallocated space) causing a crash. systemd parses the content of /proc/self/mountinfo and each mountpoint is passed to mount_setup_unit(), which calls unit_name_path_escape() underneath. A local attacker who is able to mount a filesystem with a very long path can crash systemd and the whole system.
This flaw is considered as having an Important impact due to the ability to stop the whole system by making systemd (PID 1) crash.
File /proc/self/mountinfo is constantly monitored by systemd and its content parsed by mount_load_proc_self_mountinfo() function whenever a change to the file is detected. Each mount entry in the file is passed to mount_setup_unit(), which calls unit_name_from_path() to retrieve the systemd unit name for the mount point and use it to check if a mount unit configuration file is available for it. Function unit_name_from_path() calls unit_name_path_escape() that uses strdupa() to duplicate the path string passed as argument, which is like strdup() but it allocates the buffer on the stack with alloca().
This issue has been addressed in the following products: Red Hat Enterprise Linux 8.1 Extended Update Support Via RHSA-2021:2724 https://access.redhat.com/errata/RHSA-2021:2724
This issue has been addressed in the following products: Red Hat Enterprise Linux 8.2 Extended Update Support Via RHSA-2021:2721 https://access.redhat.com/errata/RHSA-2021:2721
This issue has been addressed in the following products: Red Hat Enterprise Linux 8 Via RHSA-2021:2717 https://access.redhat.com/errata/RHSA-2021:2717
This bug is now closed. Further updates for individual products will be reflected on the CVE page(s): https://access.redhat.com/security/cve/cve-2021-33910
This issue has been addressed in the following products: Red Hat Virtualization 4 for Red Hat Enterprise Linux 8 Via RHSA-2021:2736 https://access.redhat.com/errata/RHSA-2021:2736
This issue has been addressed in the following products: Red Hat OpenShift Container Platform 4.7 Via RHSA-2021:2763 https://access.redhat.com/errata/RHSA-2021:2763