1 |
On 10/02/2014 07:32 PM, Steven J. Long wrote: |
2 |
> On Tue, Sep 30, 2014 at 07:52:02AM -0700, Zac Medico wrote: |
3 |
>> On 09/29/2014 04:31 PM, Steven J. Long wrote: |
4 |
>>> On Mon, Sep 29, 2014, Zac Medico wrote: |
5 |
>>>> On 09/28/2014, Steven J. Long wrote: |
6 |
>>>>> On Wed, Sep 24, 2014, Zac Medico wrote: |
7 |
>>>>>> 1) When esudo is called, it saves the current (unprivileged) bash |
8 |
>>>>>> environment to a file. |
9 |
>>>>>> |
10 |
>>>>>> 2) esudo uses IPC to request that a process with elevated privileges be |
11 |
>>>>>> launched to run a specific command using the saved environment, and that |
12 |
>>>>>> the environment of the elevated process be saved to a file after the |
13 |
>>>>>> command completes. |
14 |
>>>>> |
15 |
>>>>> I don't think it's going to be quite that easy to get the output env, |
16 |
>>>>> certainly not from some random command; tbh I don't even see the need |
17 |
>>>>> for it, unless I'm missing something. From the "elevated process" after |
18 |
>>>>> it waits on the child, but not from the child unless you control the |
19 |
>>>>> code. |
20 |
>>>> |
21 |
>>>> We control the shell code that launches the requested command, so we can |
22 |
>>>> save the environment after the requested command completes (using a |
23 |
>>>> modified version of our existing environment persistence code). |
24 |
>>> |
25 |
>>> Yeah but think it through; the "elevated process" inherits its environment |
26 |
>>> from us (current state, as normal). It runs a child process: nothing in the |
27 |
>>> env of that child is going to affect our env, by definition. The command |
28 |
>>> completes, and we save back the same env we started with. |
29 |
>>> |
30 |
>>> Sure, the child inherits its env from us, but we don't need to do anything |
31 |
>>> to make that happen: it's standard. In fact we take efforts to clean the |
32 |
>>> env in some situations for that reason. |
33 |
>>> |
34 |
>>> I just can't see it working, apart from perhaps where a command outputs |
35 |
>>> settings which should be run through eval. In which case, eval them |
36 |
>>> in ebuild space after the command has output whatever under esudo. To |
37 |
>>> be flexible, you're going to want to save them anyway for later use, |
38 |
>>> which again implies that happening in the ebuild/eclass. |
39 |
>> |
40 |
>> You're thinking in terms of a SUID helper like sudo. The implementation |
41 |
>> that I've been suggesting does not involve a SUID helper. |
42 |
> |
43 |
> No, I'm thinking in terms of "a process with elevated privileges" running |
44 |
> "a specific command"; whether that first process is started by us or not, |
45 |
> is irrelevant to whether it can get the environment from a child process |
46 |
> we have no control over, after it "completes". |
47 |
|
48 |
You're assuming that we have no control over the child process, which |
49 |
would be true with a SUID helper like sudo (in the absence of a wrapper |
50 |
script, see below) that is only designed to run a specific command and |
51 |
then exit without saving the enviroment. |
52 |
|
53 |
However, imagine a helper that is designed to run a requested shell |
54 |
command and then save the environment before it exits. It could be done |
55 |
with sudo if you simply required that the first argument to sudo be a |
56 |
wrapper script that executes the requested command and then saves the |
57 |
environment. For example, consider the following usage: |
58 |
|
59 |
sudo /foo/bar/wrapper.sh <requested shell command with arguments> |
60 |
|
61 |
If the sudo command is constructed shown above, then wrapper.sh can load |
62 |
an arbitrary environment, execute the requested shell command with |
63 |
arguments, and then save the resulting environment afterwards. |
64 |
|
65 |
> Sure it can save its own, but since it's a generic "run any command" helper, |
66 |
> it can't do much more than give us back what we gave it, unless you're |
67 |
> talking about echoing back settings, in the manner of gpg et al, which |
68 |
> by definition is not about the saved env. That's why we have to use that |
69 |
> format in the first place; because the env setting must be done by the |
70 |
> process which wants to use it (have it inherited for child processes), |
71 |
> for the same reason: a child process can never affect the parent env. |
72 |
|
73 |
We could implement esudo so that it will insert wrapper.sh into the sudo |
74 |
arguments, so that the caller doesn't have to know anything about the |
75 |
wrapper.sh implementation details. For example: |
76 |
|
77 |
esudo <requested shell command with arguments> |
78 |
|
79 |
So, the privilege escalation mechanism is indeed irrelevant, as long as |
80 |
there's some opportunity to insert a wrapper script that runs with |
81 |
escalated privileges, allowing it to load/save the environment at the |
82 |
appropriate time during shell execution. |
83 |
|
84 |
>> Instead, IPC |
85 |
>> would be used to request that the privileged parent process launch a new |
86 |
>> privileged process on behalf of esudo. In this context, unless the esudo |
87 |
>> implementation provides explicit support for environment inheritance, |
88 |
>> the new privileged process will not inherit any environment from the |
89 |
>> environment where esudo was called. |
90 |
> |
91 |
> Well, assuming that were the implementation, that explains why you'd want |
92 |
> to save the env off, so that the privileged helper can access it. It still |
93 |
> sounds like more work in the long run in terms of what's happening, but |
94 |
> regardless: it doesn't get you the resultant env from the child command. |
95 |
|
96 |
Except that it is possible to save the resultant env from the child |
97 |
command, using a wrapper as described above. |
98 |
|
99 |
> But like I said, that's of dubious utility in any case. I think we should |
100 |
> just forget about it. |
101 |
|
102 |
It may have dubious utility, but it's still possible, nonetheless. |
103 |
|
104 |
>>> So we already have to deal with the user part of userpriv, as admins. |
105 |
>>> |
106 |
>>> On the implementation side, it makes a lot of sense: we delegate the |
107 |
>>> worry to a package used cross-distro for this specific purpose. In fact |
108 |
>>> this conversation has made me understand ubuntu a bit more, where I |
109 |
>>> always used to smile at the overuse of sudo. I certainly wouldn't |
110 |
>>> want the implementation headache of maintaining a secure clone. |
111 |
>> |
112 |
>> The IPC implementation that I've suggested does not involve an SUID |
113 |
>> helper, so it is much more secure. Security would rely on the permission |
114 |
>> bits of the named pipes that are used to implement IPC. |
115 |
> |
116 |
> I see, so presumably there's a fifo pair, that only the portage user can |
117 |
> access (likely at dir level too), one read-only? On the other end of which |
118 |
> you have a waiting process, ie a daemon, in the classic sense, with root |
119 |
> privilege, so it can run any command as any user, with any set of caps |
120 |
> required. If you're using IPC to request a process with privilege be |
121 |
> launched, something's got to be listening to the other end. |
122 |
|
123 |
Yes, this is how ebuild helpers like has_version and best_version |
124 |
already work. The IPC system can easily be extended to handle privilege |
125 |
escalation commands. |
126 |
|
127 |
> I don't see how that's "more secure", but then I don't really care how you |
128 |
> implement it, either ;) It's certainly less deps, I guess. |
129 |
|
130 |
Well, a named pipe that is only readable/writable by a specific user is |
131 |
inherently more secure that a SUID binary that can be executed by any user. |
132 |
|
133 |
> It still just sounds like a reimpl of sudo, by an indirect method (root |
134 |
> userland daemon, as opposed to kernel suid) leading to a lot more going |
135 |
> on at runtime (env saving to file, reloading in a new child process |
136 |
> from the privileged daemon, before we can start the actual command.) |
137 |
|
138 |
Well, the daemon is already there listening for commands such as |
139 |
has_version and best_version. Extending it to handle privilege |
140 |
escalation would be fairly easy. The overhead involved is negligible. |
141 |
For things like has_version and best_version, the daemon approach is |
142 |
actually much more efficient than the alternatives, since the daemon has |
143 |
access to relatively long-lived database instances that would otherwise |
144 |
have to be instantiated for each has_version/best_version call. |
145 |
|
146 |
> And as above, it cannot get us the env after randomcmd completes, but |
147 |
> that's orthogonal, since nothing can, and programs aren't written |
148 |
> to output to their env, since the parent can't access it. |
149 |
|
150 |
Again, a wrapper script like wrapper.sh described above would have |
151 |
access to the resultant env. |
152 |
|
153 |
> I assume you have code in mind for this already, perhaps from another |
154 |
> project? If so, and it's a reasonable maintenance burden, ie not |
155 |
> much needs to change once it's up and running correctly, then fair |
156 |
> enough. |
157 |
|
158 |
What I have in mind is the existing IPC system that portage already uses |
159 |
to implement commands like has_version and best_version. |
160 |
|
161 |
> Though from what I've seen even Linux-specific projects just |
162 |
> exec the command, after setting privileges, namespace etc as |
163 |
> appropriate, from a suid helper. |
164 |
|
165 |
An SUID helper would certainly work. However, given the existing IPC |
166 |
infrastructure, I would use IPC. |
167 |
|
168 |
> Are you sure you don't want to borrow someone else's code for a suid |
169 |
> helper instead? Not sure what a daemon buys you, apart from extra |
170 |
> maintenance overhead (listener, loading env, as well as what a suid |
171 |
> helper would do, and a protocol for communication, which no doubt is |
172 |
> going to change over time) plus an attack vector for someone who can |
173 |
> crack portage or python at any future point, or just get portage uid |
174 |
> via some other vector; for a relatively infrequent operation. |
175 |
|
176 |
The portage user/group is already a possible attack vector: |
177 |
|
178 |
https://bugs.gentoo.org/show_bug.cgi?id=149062 |
179 |
|
180 |
For this reason, it's very important not to grant access to this |
181 |
user/group to untrusted users. |
182 |
-- |
183 |
Thanks, |
184 |
Zac |