Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 915330 - sys-apps/portage-3.0.51 - emerge: distfile integrity check and unpack is not atomic
Summary: sys-apps/portage-3.0.51 - emerge: distfile integrity check and unpack is not ...
Status: CONFIRMED
Alias: None
Product: Portage Development
Classification: Unclassified
Component: Enhancement/Feature Requests (show other bugs)
Hardware: All Linux
: Normal normal
Assignee: Portage team
URL:
Whiteboard:
Keywords: InVCS, PullRequest
Depends on: 915120
Blocks:
  Show dependency tree
 
Reported: 2023-10-07 10:50 UTC by klamp
Modified: 2023-10-20 00:54 UTC (History)
7 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
man/make.conf.5: note locations with trust issues (bug915330-make.conf.patch,4.33 KB, patch)
2023-10-09 20:51 UTC, Mike Gilbert
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description klamp 2023-10-07 10:50:53 UTC
Based on strace and brief source reading, I have come to conclusion that distfile integrity check and unpack is not atomic operation. This may allow attack, when distfile is changed after checksums were verified, but before distfile is unpacked.

This implies, that to ensure security, DISTDIR must be trusted location. But, based on my experience of long time gentoo user, this does not seem to be sufficiently documented. Because checksums are verified during every package merge, some users may fall into false sense of security and put DISTDIR on network share.

Another issue is, that even if DISTDIR is local, emerge does not check permissions to ensure that distfile is not writable by other users than portage.
Comment 1 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2023-10-08 06:10:54 UTC
(Manually expanded the portage team members to workaround the BZ limitation wrt aliases.)

zac: would you mind taking a look? IIRC you handled a bunch of TOCTOU stuff in the past but it was before my time
Comment 2 Zac Medico gentoo-dev 2023-10-08 20:40:42 UTC
(In reply to klamp from comment #0)
> This implies, that to ensure security, DISTDIR must be trusted location.

As discussed in bug 149062, this applies to essentially any directory where portage stores data, including PKGDIR, PORTAGE_TMPDIR/portage, CCACHE_DIR, and repository locations referenced by repos.conf.

> Another issue is, that even if DISTDIR is local, emerge does not check
> permissions to ensure that distfile is not writable by other users than
> portage.

Permission checks for all of these directories would definitely improve security. As it is, portage will emit a warning about the portage group in cases when the current operation requires privileges to one of these directories and the current user doesn't have sufficient privileges:

https://gitweb.gentoo.org/proj/portage.git/commit/?id=fd76b435d5ce953e91a0efa8f6706aa3bd505f62
Comment 3 Mike Gilbert gentoo-dev 2023-10-09 17:33:20 UTC
> Because checksums are verified during every package merge, some users may fall into false sense of security and put DISTDIR on network share.

Having DISTDIR on a network share doesn't necessarily make it "untrusted". It really depends on who has write access to the network share.
Comment 4 klamp 2023-10-09 19:48:49 UTC
(In reply to Zac Medico from comment #2)
> (In reply to klamp from comment #0)
> > This implies, that to ensure security, DISTDIR must be trusted location.
> 
> As discussed in bug 149062, this applies to essentially any directory where
> portage stores data, including PKGDIR, PORTAGE_TMPDIR/portage, CCACHE_DIR,
> and repository locations referenced by repos.conf.

Problem is that with those other directories it falls into "common sense", maybe except PKGDIR if packages can be and are crypto signed. But DISTDIR is specifically used to store files which are cryptographically verified before use, which may lead users to believe that it is safe to use not trusted location. 

Recommend way to setup distfile cache is via apt-cacher [1], but users attempted network share too [2]. I suspect that average user is not aware that there exist chain of trust between gentoo system and DISTDIR server.

[1] https://wiki.gentoo.org/wiki/Local_distfiles_cache
[2] https://forums.gentoo.org/viewtopic-t-412722.html
Comment 5 Mike Gilbert gentoo-dev 2023-10-09 19:55:12 UTC
(In reply to klamp from comment #4)

Pages on the Gentoo wiki written by users are not official documentation and should bot be treated as such.
Comment 6 Mike Gilbert gentoo-dev 2023-10-09 20:08:16 UTC
We could add some text to make.conf(5) to document the various locations that are security-sensitive.

If we want to treat DISTDIR as untrusted, we could potentially copy the the distfiles to a location under PORTAGE_TMPDIR before verification, instead of using symlinks.
Comment 7 Zac Medico gentoo-dev 2023-10-09 20:25:39 UTC
Not sure if all of the unpackers would react well to the archive being an un-seekable pipe, but anyway we could tee the archive to the unpacker and a digest checker simultaneously, so that the digest check and unpack are atomic with respect to each other. In this case, the unpacker would refer to the archive as /dev/stdin or /dev/fd/${fd}, which would be a pipe that reads from tee.
Comment 8 Mike Gilbert gentoo-dev 2023-10-09 20:39:29 UTC
(In reply to Zac Medico from comment #7)

That sounds overly complex and error-prone.

To make that work we would need to delay Manifest verification to the unpack phase, or validate the Manifest multiple times.
Comment 9 Mike Gilbert gentoo-dev 2023-10-09 20:51:48 UTC
Created attachment 872439 [details, diff]
man/make.conf.5: note locations with trust issues
Comment 10 Mike Gilbert gentoo-dev 2023-10-10 14:20:12 UTC
(In reply to Zac Medico from comment #7)

I don't understand how this would be implemented without creating a copy of the distfiles, either in memory or on disk.

Basically, we have to read the entire file to compute the Manifest hashes. And we can't pass the data to the unpacker until after the Manifest has been validated.

Am I missing something?
Comment 11 Zac Medico gentoo-dev 2023-10-10 14:46:57 UTC
(In reply to Mike Gilbert from comment #10)
> (In reply to Zac Medico from comment #7)
> 
> I don't understand how this would be implemented without creating a copy of
> the distfiles, either in memory or on disk.

Most of the unpackers can probably handle an unseekable stream as input, so it's enough to use a pipe from tee which only buffers a portion of the file. For example, compressed tar streams do not require seek, and I've just checked unzip -l /dev/stdin and 7z l /dev/stdin which both appear to work on zip files. However, we'd have to test all of unpackers to see if they work, and there's really no guarantee that behavior will not change over time for some of them. However, it might be argued that all unpackers *should* support this type of use case, given that using stdin for input files is a fairly common unix thing since it avoids the need for temporary files.

> Basically, we have to read the entire file to compute the Manifest hashes.
> And we can't pass the data to the unpacker until after the Manifest has been
> validated.
> 
> Am I missing something?

When you consider the possibility of vulnerabilities in the unpackers, yes it's definitely safer to check the hashes in advance. Checking them simultaneous to unpack would leave room for some kind of exploit to occur before the manifest check can prevent it. Such an exploit might be unlikely, but it's certainly not unheard of.
Comment 12 Larry the Git Cow gentoo-dev 2023-10-11 18:34:29 UTC
The bug has been referenced in the following commit(s):

https://gitweb.gentoo.org/proj/portage.git/commit/?id=b2f543f9b3815ac8e7d7f53ab387ce51f4b8311e

commit b2f543f9b3815ac8e7d7f53ab387ce51f4b8311e
Author:     Mike Gilbert <floppym@gentoo.org>
AuthorDate: 2023-10-09 20:46:31 +0000
Commit:     Mike Gilbert <floppym@gentoo.org>
CommitDate: 2023-10-09 20:46:31 +0000

    man/make.conf.5: note locations with trust issues
    
    Bug: https://bugs.gentoo.org/915330
    Signed-off-by: Mike Gilbert <floppym@gentoo.org>

 man/make.conf.5 | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
Comment 13 Zac Medico gentoo-dev 2023-10-11 18:43:28 UTC
(In reply to Zac Medico from comment #11)
> checked unzip -l /dev/stdin and 7z l /dev/stdin which both appear to work on
> zip files.

Actually this is not true. They work when /dev/stdin is a file redirect, but not if it's a pipe from cat.
Comment 14 Larry the Git Cow gentoo-dev 2023-10-20 00:51:31 UTC
The bug has been closed via the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=3500483f75789c36e379c1b6546a09df7c11e2b1

commit 3500483f75789c36e379c1b6546a09df7c11e2b1
Author:     Sam James <sam@gentoo.org>
AuthorDate: 2023-10-20 00:49:33 +0000
Commit:     Sam James <sam@gentoo.org>
CommitDate: 2023-10-20 00:51:00 +0000

    sys-apps/portage: add 3.0.53
    
    Closes: https://bugs.gentoo.org/915120
    Closes: https://bugs.gentoo.org/821529
    Closes: https://bugs.gentoo.org/914441
    Closes: https://bugs.gentoo.org/914722
    Closes: https://bugs.gentoo.org/914873
    Closes: https://bugs.gentoo.org/915099
    Closes: https://bugs.gentoo.org/915123
    Closes: https://bugs.gentoo.org/915128
    Closes: https://bugs.gentoo.org/915136
    Closes: https://bugs.gentoo.org/915330
    Closes: https://bugs.gentoo.org/915494
    Closes: https://bugs.gentoo.org/915834
    Closes: https://bugs.gentoo.org/915903
    Closes: https://bugs.gentoo.org/900224
    Signed-off-by: Sam James <sam@gentoo.org>

 sys-apps/portage/Manifest              |   1 +
 sys-apps/portage/portage-3.0.53.ebuild | 238 +++++++++++++++++++++++++++++++++
 2 files changed, 239 insertions(+)
Comment 15 Sam James archtester Gentoo Infrastructure gentoo-dev Security 2023-10-20 00:54:52 UTC
We could keep this open as an enhancement request. Not sure I feel that strongly about it.