Bugzilla – Bug 1155075
VUL-0: CVE-2019-3691: munge: LPE from munge to root
Last modified: 2020-05-12 18:42:45 UTC
167 %post 168 if [ $1 -eq 1 ] 169 then 170 %{fixperm %{_localstatedir}/log/munge} 171 %{fixperm %{_localstatedir}/log/munge/munged.log} 172 %{fixperm %{_localstatedir}/run/munge} 173 fi 174 if [ ! -e %{_sysconfdir}/munge/munge.key -a -c /dev/urandom ]; then 175 /bin/dd if=/dev/urandom bs=1 count=1024 \ 176 >%{_sysconfdir}/munge/munge.key 2>/dev/null 177 fi 178 /bin/chown %munge_u:%munge_g %{_sysconfdir}/munge/munge.key 179 /bin/chmod 0400 %{_sysconfdir}/munge/munge.key allows LPE from munge to root. POC: sh-5.0$ id uid=464(munge) gid=463(munge) groups=463(munge) sh-5.0$ pwd /etc/munge sh-5.0$ rm munge.key sh-5.0$ ln -s /test/shadow munge.key reinstall/update munge as root sh-5.0$ ls -lah /test/ total 12K drwxr-xr-x 2 root root 4.0K Oct 25 11:01 . drwxr-xr-x 23 root root 4.0K Oct 25 11:01 .. -r-------- 1 munge munge 1.2K Oct 25 11:01 shadow The fixperm calls in post/postun have similar issues
So what's your suggestion to fix this? Would a test for the file not being a symbolic link be sufficient?
(In reply to Egbert Eich from comment #1) For the chown -R there's no easy way to fix it. I've been looking for supporting tools that could be used here, but without success so far. But since that requires fs.protected_hardlinks=0 (and we have it enabled by default) this is low priority ATM. For the munge.key issue: You could use runuser to create the file as the munge user. If you set the umask correctly you can remove the chown and chmod. It also prevents the attacker from racing with the if/dd construct and use it to overwrite arbitrary files
We'll track this via CVE-2019-3691. Can be made public as soon as we release an update
(In reply to Johannes Segitz from comment #2) > (In reply to Egbert Eich from comment #1) > For the chown -R there's no easy way to fix it. I've been looking for > supporting tools that could be used here, but without success so far. But > since that requires fs.protected_hardlinks=0 (and we have it enabled by > default) this is low priority ATM. > > For the munge.key issue: You could use runuser to create the file as the > munge user. If you set the umask correctly you can remove the chown and > chmod. It also prevents the attacker from racing with the if/dd construct > and use it to overwrite arbitrary files I'm using chown (and the fixperm macro) as well as chmod to fix the ownership in case it was set differently in an earlier installation. This cannot be handled by a mask. Looking at chown, if the only concern is the fact that it is a link, we can use chown -h to avoid that we follow the link. The only consequence would be that if the file existed and belonged to the attacker it no longer does - even if the file was set suid before, and the attacker would manage to execute it before the chown happens, the damage would be contained: the munge user/group cannot really do much.
Actually, set NEEDINFO again - see previous comment.
Is this better? %define fixperm() [ -e %1 ] && /bin/chown -h %munge_u:%munge_g %1 [...] unset tmpfile if [ ! -e %{_sysconfdir}/munge/munge.key ]; then if [ -a -c /dev/urandom ]; then tmpfile=$(mktemp /tmp/tmpfile-XXXXXXX) /bin/dd if=/dev/urandom bs=1 count=1024 > $tmpfile 2>/dev/null fi elif [ $(/usr/bin/stat -c %U:%G:%a %{_sysconfdir}/munge/munge.key) != \ %munge_u:%munge_g:400 ]; then tmpfile=$(/usr/bin/mktemp /tmp/tmpfile-XXXXXXX) /usr/bin/cat %{_sysconfdir}/munge/munge.key > $tmpfile fi if [ -n "$tmpfile" ]; then /bin/chmod 0400 $tmpfile /bin/chown -h %munge_u:%munge_g $tmpfile /bin/mv $tmpfile %{_sysconfdir}/munge/munge.key fi
Further notes: Here chown/chmod are not used recursively. - To prevent chown from following links, one can use the -h option. This will mitigate your exploit example. - umask is not really feasible as we also may have to fix up old ownerships - the munge user is separate and has no root rights. Create files in these locations requires much more rights than one would be able to gain from becoming the munge user. In your exploit example, one was the munge user already. 'Games' creating a suid file and having the installation chown it to another user will not allow an exploit either: chown will reset the suid bit. So I believe, the proposed change addresses possible security concerns.
(In reply to Egbert Eich from comment #7) Thank you for your work here and the detailed explanations. That's better, but with the usage of cat elif [ $(/usr/bin/stat -c %U:%G:%a %{_sysconfdir}/munge/munge.key) != \ %munge_u:%munge_g:400 ]; then tmpfile=$(/usr/bin/mktemp /tmp/tmpfile-XXXXXXX) /usr/bin/cat %{_sysconfdir}/munge/munge.key > $tmpfile fi if [ -n "$tmpfile" ]; then /bin/chmod 0400 $tmpfile /bin/chown -h %munge_u:%munge_g $tmpfile /bin/mv $tmpfile %{_sysconfdir}/munge/munge.key fi an attacker can read arbitrary files by symlinking to them. The symlink will yield munge:munge:777 and therefor trigger the elif. cat reads the linked file and copies the content into $tmpfile, which is then transfered back You could create a temp directory and then copy the file there without dereferencing symlinks tmpdir=$(/usr/bin/mktemp -d /tmp/tmpfile-XXXXXXX) cp -P /etc/munge/munge.key $tmpdir now you have the file in a directory that root controls. Here you can test if it's a regular file and then act on it, since the attacker can't interfere anymore
New proposal using a temporary directory instead of just a temporary file. unset tmpfile tmpdir=$(mktemp -d /tmp/tmpdir-XXXXXXXXX) if [ -e %{_sysconfdir}/munge/munge.key ]; then # Preserve symlink so we can check for it cp -pP %{_sysconfdir}/munge/munge.key ${tmpdir} fi # Make sure this is no symlinks - this may have been created by an attacker! if [ -e ${tmpdir}/munge.key -a ! -h ${tmpdir}/munge.key ]; then if [ $(/usr/bin/stat -c %U:%G:%a ${tmpdir}/munge.key) != \ %munge_u:%munge_g:400 ]; then tmpfile=${tmpdir}/munge.key fi else /usr/bin/rm -f ${tmpdir}/munge.key if [ -c /dev/urandom ]; then tmpfile=${tmpdir}/munge.key /bin/dd if=/dev/urandom bs=1 count=1024 > $tmpfile 2>/dev/null fi fi if [ -n "$tmpfile" ]; then /bin/chmod 0400 $tmpfile /bin/chown -h %munge_u:%munge_g $tmpfile /bin/mv $tmpfile %{_sysconfdir}/munge/munge.key fi /usr/bin/rm -rf ${tmpdir}
That looks good, but you need to add -f to the mv to handle the case where the file already exists. Can you please submit with this last change? Thank you!
(In reply to Johannes Segitz from comment #10) > That looks good, but you need to add -f to the mv to handle the case where Indeed! > the file already exists. Can you please submit with this last change? > > Thank you! Done. SR#204600 and SR#204601.
Submitted to Factory: SR ID #754486
This is an autogenerated message for OBS integration: This bug (1155075) was mentioned in https://build.opensuse.org/request/show/754491 Factory / munge
SUSE-SU-2019:3190-1: An update that fixes one vulnerability is now available. Category: security (moderate) Bug References: 1155075 CVE References: CVE-2019-3691 Sources used: SUSE Linux Enterprise Module for Open Buildservice Development Tools 15-SP1 (src): munge-0.5.13-4.3.1 SUSE Linux Enterprise Module for HPC 15-SP1 (src): munge-0.5.13-4.3.1 SUSE Linux Enterprise Module for HPC 15 (src): munge-0.5.13-4.3.1 NOTE: This line indicates an update has been released for the listed product(s). At times this might be only a partial fix. If you have questions please reach out to maintenance coordination.
openSUSE-SU-2019:2670-1: An update that fixes one vulnerability is now available. Category: security (moderate) Bug References: 1155075 CVE References: CVE-2019-3691 Sources used: openSUSE Leap 15.1 (src): munge-0.5.13-lp151.4.3.1
SUSE-SU-2020:1144-1: An update that solves one vulnerability and has one errata is now available. Category: security (moderate) Bug References: 1155075,1160075 CVE References: CVE-2019-3691 Sources used: SUSE Linux Enterprise Module for HPC 12 (src): munge-0.5.14-3.6.1 NOTE: This line indicates an update has been released for the listed product(s). At times this might be only a partial fix. If you have questions please reach out to maintenance coordination.