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"
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.
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.
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.
(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.
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.
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.
(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.
(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.
I'll mark it fixed when it's released in portage-2.1.7.18.
This is fixed in 2.1.8 and 2.2_rc64.