Bug 1970887 (CVE-2021-33910)

Summary: CVE-2021-33910 systemd: uncontrolled allocation on the stack in function unit_name_path_escape leads to crash
Product: [Other] Security Response Reporter: msiddiqu
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED ERRATA QA Contact:
Severity: high Docs Contact:
Priority: high    
Version: unspecifiedCC: bdettelb, caswilli, dblechte, dfediuck, eclarizi, eedri, fedoraproject, filbranden, fjansen, flepied, jamacku, jnakfour, kasong, kaycoth, lnacshon, lnykryn, lpoetter, mcascell, mgoldboi, michal.skrivanek, msekleta, mvanderw, nobody, psegedy, rschiron, sbonazzo, security-response-team, sherold, ssahani, s, systemd-maint-list, systemd-maint, tomckay, vmugicag, yturgema, yuwatana, zbyszek, zjedrzej
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: systemd 249 Doc Type: If docs needed, set a value
Doc Text:
A flaw was found in systemd. The use of alloca function with an uncontrolled size in function unit_name_path_escape allows a local attacker, able to mount a filesystem on a very long path, to crash systemd and the whole system by allocating a very large space in the stack. The highest threat from this vulnerability is to the system availability.
Story Points: ---
Clone Of: Environment:
Last Closed: 2021-07-21 03:54:50 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1976591, 1974696, 1974697, 1974698, 1974699, 1974700, 1974721, 1976592, 1976593, 1976594, 1976595, 1976596, 1976597, 1979859, 1984020, 1984299    
Bug Blocks: 1974594    

Description msiddiqu 2021-06-11 12:08:50 UTC
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

Comment 1 Riccardo Schirone 2021-06-22 10:26:11 UTC
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);
}
```

Comment 2 Riccardo Schirone 2021-06-22 10:29:05 UTC
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

Comment 5 Riccardo Schirone 2021-06-22 10:50:25 UTC
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.

Comment 7 Riccardo Schirone 2021-06-22 16:05:01 UTC
This flaw is considered as having an Important impact due to the ability to stop the whole system by making systemd (PID 1) crash.

Comment 20 Riccardo Schirone 2021-07-06 10:16:14 UTC
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().

Comment 23 errata-xmlrpc 2021-07-20 22:29:03 UTC
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

Comment 24 errata-xmlrpc 2021-07-20 22:32:27 UTC
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

Comment 25 errata-xmlrpc 2021-07-21 00:28:20 UTC
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

Comment 26 Product Security DevOps Team 2021-07-21 03:54:50 UTC
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

Comment 28 errata-xmlrpc 2021-07-22 15:06:50 UTC
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

Comment 29 errata-xmlrpc 2021-07-26 16:40:32 UTC
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