Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH] update LOGNAME variable when appropriate (534722)
Date: Mon, 19 Jan 2015 03:13:55
Message-Id: 1421637215-1505-1-git-send-email-zmedico@gentoo.org
1 Fix userpriv, usersync, and userfetch code to update the LOGNAME
2 variable when dropping privileges, so that tools that rely on it will
3 work properly. Note that bin/save-ebuild-env.sh filters LOGNAME,
4 preventing stale LOGNAME settings from persisting between ebuild phases
5 that run with different privileges.
6
7 X-Gentoo-Bug: 534722
8 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=534722
9 ---
10 pym/portage/package/ebuild/doebuild.py | 40 ++++++++++++++++++++++++----------
11 pym/portage/package/ebuild/fetch.py | 7 +++++-
12 pym/portage/sync/controller.py | 18 ++++++++++-----
13 3 files changed, 46 insertions(+), 19 deletions(-)
14
15 diff --git a/pym/portage/package/ebuild/doebuild.py b/pym/portage/package/ebuild/doebuild.py
16 index f43dddc..791b5c3 100644
17 --- a/pym/portage/package/ebuild/doebuild.py
18 +++ b/pym/portage/package/ebuild/doebuild.py
19 @@ -1493,8 +1493,10 @@ def spawn(mystring, mysettings, debug=False, free=False, droppriv=False,
20 fakeroot = fakeroot and uid != 0 and portage.process.fakeroot_capable
21 portage_build_uid = os.getuid()
22 portage_build_gid = os.getgid()
23 + logname = None
24 if uid == 0 and portage_uid and portage_gid and hasattr(os, "setgroups"):
25 if droppriv:
26 + logname = portage.data._portage_username
27 keywords.update({
28 "uid": portage_uid,
29 "gid": portage_gid,
30 @@ -1579,21 +1581,35 @@ def spawn(mystring, mysettings, debug=False, free=False, droppriv=False,
31 spawn_func = selinux.spawn_wrapper(spawn_func,
32 mysettings["PORTAGE_SANDBOX_T"])
33
34 - if keywords.get("returnpid"):
35 - return spawn_func(mystring, env=mysettings.environ(),
36 - **portage._native_kwargs(keywords))
37 + logname_backup = None
38 + if logname is not None:
39 + logname_backup = mysettings.configdict["env"].get("LOGNAME")
40 + mysettings.configdict["env"]["LOGNAME"] = logname
41
42 - proc = EbuildSpawnProcess(
43 - background=False, args=mystring,
44 - scheduler=SchedulerInterface(portage._internal_caller and
45 - global_event_loop() or EventLoop(main=False)),
46 - spawn_func=spawn_func,
47 - settings=mysettings, **portage._native_kwargs(keywords))
48 + try:
49 + if keywords.get("returnpid"):
50 + return spawn_func(mystring, env=mysettings.environ(),
51 + **portage._native_kwargs(keywords))
52 +
53 + proc = EbuildSpawnProcess(
54 + background=False, args=mystring,
55 + scheduler=SchedulerInterface(portage._internal_caller and
56 + global_event_loop() or EventLoop(main=False)),
57 + spawn_func=spawn_func,
58 + settings=mysettings, **portage._native_kwargs(keywords))
59 +
60 + proc.start()
61 + proc.wait()
62
63 - proc.start()
64 - proc.wait()
65 + return proc.returncode
66
67 - return proc.returncode
68 + finally:
69 + if logname is None:
70 + pass
71 + elif logname_backup is None:
72 + mysettings.configdict["env"].pop("LOGNAME", None)
73 + else:
74 + mysettings.configdict["env"]["LOGNAME"] = logname_backup
75
76 # parse actionmap to spawn ebuild with the appropriate args
77 def spawnebuild(mydo, actionmap, mysettings, debug, alwaysdep=0,
78 diff --git a/pym/portage/package/ebuild/fetch.py b/pym/portage/package/ebuild/fetch.py
79 index 2424ff3..7b856a2 100644
80 --- a/pym/portage/package/ebuild/fetch.py
81 +++ b/pym/portage/package/ebuild/fetch.py
82 @@ -73,10 +73,12 @@ def _spawn_fetch(settings, args, **kwargs):
83 2 : sys.__stdout__.fileno(),
84 }
85
86 + logname = None
87 if "userfetch" in settings.features and \
88 os.getuid() == 0 and portage_gid and portage_uid and \
89 hasattr(os, "setgroups"):
90 kwargs.update(_userpriv_spawn_kwargs)
91 + logname = portage.data._portage_username
92
93 spawn_func = spawn
94
95 @@ -93,8 +95,11 @@ def _spawn_fetch(settings, args, **kwargs):
96 # proxy variables, as in bug #315421).
97 phase_backup = settings.get('EBUILD_PHASE')
98 settings['EBUILD_PHASE'] = 'fetch'
99 + env = settings.environ()
100 + if logname is not None:
101 + env["LOGNAME"] = logname
102 try:
103 - rval = spawn_func(args, env=settings.environ(), **kwargs)
104 + rval = spawn_func(args, env=env, **kwargs)
105 finally:
106 if phase_backup is None:
107 settings.pop('EBUILD_PHASE', None)
108 diff --git a/pym/portage/sync/controller.py b/pym/portage/sync/controller.py
109 index 128a38e..d2c606d 100644
110 --- a/pym/portage/sync/controller.py
111 +++ b/pym/portage/sync/controller.py
112 @@ -205,6 +205,7 @@ class SyncManager(object):
113 user = None
114 group = None
115 home = None
116 + logname = None
117
118 spl = sync_user.split(':', 1)
119 if spl[0]:
120 @@ -217,10 +218,11 @@ class SyncManager(object):
121 except (ValueError, KeyError):
122 writemsg("!!! User '%s' invalid or does not exist\n"
123 % username, noiselevel=-1)
124 - return (user, group, home)
125 + return (logname, user, group, home)
126 user = pw.pw_uid
127 group = pw.pw_gid
128 home = pw.pw_dir
129 + logname = pw.pw_name
130
131 if len(spl) > 1:
132 groupname = spl[1]
133 @@ -232,14 +234,15 @@ class SyncManager(object):
134 except (ValueError, KeyError):
135 writemsg("!!! Group '%s' invalid or does not exist\n"
136 % groupname, noiselevel=-1)
137 - return (user, group, home)
138 + return (logname, user, group, home)
139
140 group = gp.gr_gid
141
142 - return (user, group, home)
143 + return (logname, user, group, home)
144
145 # user or user:group
146 - (uid, gid, home) = get_sync_user_data(repo.sync_user)
147 + (logname, uid, gid, home) = get_sync_user_data(
148 + repo.sync_user)
149 if uid is not None:
150 spawn_kwargs["uid"] = uid
151 self.usersync_uid = uid
152 @@ -248,6 +251,8 @@ class SyncManager(object):
153 spawn_kwargs["groups"] = [gid]
154 if home is not None:
155 spawn_kwargs["env"]["HOME"] = home
156 + if logname is not None:
157 + spawn_kwargs["env"]["LOGNAME"] = logname
158
159 if st is None:
160 perms = {'mode': 0o755}
161 @@ -268,7 +273,7 @@ class SyncManager(object):
162 (st.st_uid != os.getuid() and st.st_mode & 0o700 or
163 st.st_gid != os.getgid() and st.st_mode & 0o070)):
164 try:
165 - homedir = pwd.getpwuid(st.st_uid).pw_dir
166 + pw = pwd.getpwuid(st.st_uid)
167 except KeyError:
168 pass
169 else:
170 @@ -278,7 +283,8 @@ class SyncManager(object):
171 spawn_kwargs["uid"] = st.st_uid
172 spawn_kwargs["gid"] = st.st_gid
173 spawn_kwargs["groups"] = [st.st_gid]
174 - spawn_kwargs["env"]["HOME"] = homedir
175 + spawn_kwargs["env"]["HOME"] = pw.pw_dir
176 + spawn_kwargs["env"]["LOGNAME"] = pw.pw_name
177 umask = 0o002
178 if not st.st_mode & 0o020:
179 umask = umask | 0o020
180 --
181 2.0.5

Replies