Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 298479 - FEATURES=userpriv changes uid to portage, but leaves $USER set to "root" in ebuild phase compile
Summary: FEATURES=userpriv changes uid to portage, but leaves $USER set to "root" in e...
Status: RESOLVED FIXED
Alias: None
Product: Portage Development
Classification: Unclassified
Component: Core (show other bugs)
Hardware: All Linux
: Normal normal (vote)
Assignee: Portage team
URL:
Whiteboard:
Keywords: InVCS
Depends on:
Blocks: 307597
  Show dependency tree
 
Reported: 2009-12-26 23:22 UTC by Kevin Pyle
Modified: 2010-03-03 11:18 UTC (History)
0 users

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


Attachments
Portage bashrc (bashrc,9.08 KB, text/plain)
2009-12-31 21:07 UTC, Kevin Pyle
Details
Log from running /usr/bin/emerge -1B xterm (x11-terms:xterm-250:20091231-201915.log,74.40 KB, text/plain)
2009-12-31 21:09 UTC, Kevin Pyle
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Kevin Pyle 2009-12-26 23:22:23 UTC
When the ebuild phase compile is run under FEATURES=userpriv, Portage correctly does a setuid from root to uid=250 (portage), but does not reset $USER to "portage".  I found this because I have a snippet in /etc/bash/bashrc that redirects DISTCC_DIR to a path based on $USER, and distcc started complaining that it could not access root's DISTCC_DIR.  The snippet was:

if [ -x "$TMPDIR"/.distcc/ ]; then
        export DISTCC_DIR="$TMPDIR"/.distcc/
fi

I have changed it now to avoid this problem, but it would be nice to get the environment to be consistent.  Other code could also become confused by the discrepancy between $UID (=250) and $USER (=root).

In case anyone wonders, I have DISTCC_DIR set in /etc/make.conf as well, but the shell spawned to execute the ebuild sources /etc/bash/bashrc, and the snippet as written overwrote the DISTCC_DIR variable inherited from /etc/make.conf.  I have now changed the snippet to:

if [ -z "$DISTCC_DIR" -a -n "$TMPDIR" -a -x "$TMPDIR"/.distcc/ ]; then
        export DISTCC_DIR="$TMPDIR"/.distcc/
fi


Portage 2.1.6.13 (default/linux/amd64/10.0, gcc-4.3.4, glibc-2.9_p20081201-r2, 2.6.31.9 x86_64)
=================================================================
Timestamp of tree: Sat, 19 Dec 2009 23:15:02 +0000
distcc 3.1 x86_64-pc-linux-gnu [enabled]
ccache version 2.4 [enabled]
app-shells/bash:     4.0_p35
dev-lang/python:     2.6.4
dev-util/ccache:     2.4-r7
sys-apps/baselayout: 1.12.13
sys-apps/sandbox:    1.6-r2
sys-devel/autoconf:  2.13, 2.63-r1
sys-devel/automake:  1.10.2
sys-devel/binutils:  2.18-r3
sys-devel/gcc-config: 1.4.1
sys-devel/libtool:   2.2.6b
virtual/os-headers:  2.6.30-r1
FEATURES="buildpkg ccache collision-protect distcc distlocks fixpackages parallel-fetch protect-owned sandbox severe sfperms splitdebug strict unmerge-orphans userfetch userpriv usersandbox"
Comment 1 Kevin Pyle 2009-12-26 23:39:12 UTC
Update (and feeling a bit silly): /etc/bash/bashrc is _NOT_ sourced in the Portage-spawned bash, contrary to what I initially said.  Rather, the value in /etc/make.conf is ignored because the root user who ran emerge has a DISTCC_DIR of his own in the environment from when he sourced /etc/bash/bashrc.  I should have thought of that.  Anyway, the problem reported here ($USER inconsistent with $EUID/$UID) is real, though my diagnosis for my problem was wrong, and thus fixing the inconsistency does not resolve my problem of the portage user trying to use root's DISTCC_DIR.

Unsetting DISTCC_DIR before running emerge avoids the problem that led to this investigation.  As a secondary issue, it would be nice to automatically ignore the DISTCC_DIR in the root user's environment when running as a non-root user.
Comment 2 Zac Medico gentoo-dev 2009-12-31 04:04:59 UTC
I don't even know where the USER variable comes from. It doesn't seem to come from bash since `env -i bash -c 'echo $USER'` shows nothing. Perhaps we should just filter out this variable from the ebuild environment, since there's no rule which says that this variable must be set.

As for filtering DISTCC_DIR, it would be nice if we could simply ignore all environment variables like this, but this is in opposition to legacy behavior which many people rely on. How about if we add an emerge option to ignore the calling environment entirely? You'll be able to add it to EMERGE_DEFAULT_OPTS in make.conf.
Comment 3 Kevin Pyle 2009-12-31 06:25:40 UTC
After some digging, it looks like su sets $USER when su'ing to root.  On shells running as me, $USER is my username there, but I have not yet found where that is set.  As you say, it seems to be more a convenience variable than a guaranteed one, so it is less clear whether the package manager ought to handle it.  I would be happy either with unsetting it or setting it to the account associated with $UID.

As for DISTCC_DIR: yes, the behavior of applying overrides via environment variables is useful.  However, for the specific scenario I encountered where DISTCC_DIR points to a root-only .distcc and Portage drops privileges due to userpriv, the result is distcc cannot access its state directory and falls back into local-only mode.  This scenario could be detected with a heuristic based on permissions of the target directory.  Thinking about it, I am a bit surprised (though also grateful) that Portage did not adjust the permissions via pym/portage/__init__py:_prepare_features_dirs.  Does _prepare_features_dirs ignore the environment variable and only inspect values from /etc/make.conf?

I think it would be better to avoid adding a command-line option for an admittedly somewhat rare case.  While I would like to see a heuristic to handle this case automatically, I could also see handling this with just a documentation note (and no code change) that users who export DISTCC_DIR in root's environment need to reset it for emerge, either via /etc/portage/bashrc, a bash alias, or a wrapper script.  Anyone who finds the documentation of the proposed command line option would probably also find the documentation note warning to be careful about the value of DISTCC_DIR.
Comment 4 Zac Medico gentoo-dev 2009-12-31 10:25:21 UTC
(In reply to comment #3)
> As for DISTCC_DIR: yes, the behavior of applying overrides via environment
> variables is useful.  However, for the specific scenario I encountered where
> DISTCC_DIR points to a root-only .distcc and Portage drops privileges due to
> userpriv, the result is distcc cannot access its state directory and falls back
> into local-only mode.  This scenario could be detected with a heuristic based
> on permissions of the target directory.  Thinking about it, I am a bit
> surprised (though also grateful) that Portage did not adjust the permissions
> via pym/portage/__init__py:_prepare_features_dirs.  Does _prepare_features_dirs
> ignore the environment variable and only inspect values from /etc/make.conf?

When it adjusts permissions, it uses the DISTCC_DIR value that's inherited from the calling environment (if set), otherwise it uses the value from make.conf. If you've got some code changing the value later in bashrc then that won't be accounted for.
Comment 5 Kevin Pyle 2009-12-31 21:07:00 UTC
Created attachment 214792 [details]
Portage bashrc

Strange, then.  I do not adjust DISTCC_DIR in the Portage bashrc, though I do print it when emake is called.  You can see my full bashrc in this attachment, if you are curious.  There are a few things in it that are unrelated here, and some remnants of when I was more active trying to fix bugs Diego filed for QA problems.

# grep DISTCC_DIR /etc/portage/bashrc
                for name in CHOST CBUILD CFLAGS CPPFLAGS CXXFLAGS LDFLAGS MAKEOPTS DISTCC_DIR DISTCC_HOSTS USER EUID UID PATH; do
# echo $DISTCC_DIR
/tmp/.private/root/.distcc/
# /usr/bin/emerge -1B xterm

I will attach the log from this emerge next.
Comment 6 Kevin Pyle 2009-12-31 21:09:24 UTC
Created attachment 214795 [details]
Log from running /usr/bin/emerge -1B xterm

Please excuse the noise from the instrumentation in make.  The choice of xterm was arbitrary.
Comment 7 Zac Medico gentoo-dev 2010-02-09 21:29:08 UTC
(In reply to comment #3)
> After some digging, it looks like su sets $USER when su'ing to root.  On shells
> running as me, $USER is my username there, but I have not yet found where that
> is set.  As you say, it seems to be more a convenience variable than a
> guaranteed one, so it is less clear whether the package manager ought to handle
> it.  I would be happy either with unsetting it or setting it to the account
> associated with $UID.

It's fixed to filter out $USER in svn r15332.
Comment 8 Kevin Pyle 2010-02-14 19:13:15 UTC
(In reply to comment #7)
> It's fixed to filter out $USER in svn r15332.

Thanks.  Shall I mark this fixed now, or would you prefer that I test the change first?  It looks sound.
Comment 9 Zac Medico gentoo-dev 2010-02-14 20:12:08 UTC
I'll mark it fixed when it's released in portage-2.1.7.18.
Comment 10 Zac Medico gentoo-dev 2010-03-03 11:18:09 UTC
This is fixed in 2.1.8 and 2.2_rc64.