1 |
On 01/10/2018 01:04 PM, William Hubbs wrote: |
2 |
> On Tue, Jan 09, 2018 at 08:19:24PM -0500, Michael Orlitzky wrote: |
3 |
> |
4 |
>> Ultimately, it's not safe to chown/chmod/setfacl/whatever in a directory |
5 |
>> that is not writable only by yourself and root. |
6 |
> |
7 |
> Let me try to phrase this another way. |
8 |
> |
9 |
> If the directory we are in is not owned by us or root and is group or |
10 |
> world writable, checkpath should not change the ownership or permissions |
11 |
> of the file passed to it. |
12 |
|
13 |
There are also POSIX ACLs, NFSv4 ACLs, and god-knows-what-else to worry |
14 |
about, but the above is a good start. |
15 |
|
16 |
|
17 |
>> Here's a very tedious proposal for OpenRC: ... |
18 |
>> |
19 |
>> 2. Have newpath throw a warning if it's used in a directory that is |
20 |
>> writable by someone other than root and the OpenRC user. This will |
21 |
>> prevent people from creating /foo/bar after /foo has already been |
22 |
>> created with owner "foo:foo". In other words, service script |
23 |
>> writers will be encouraged to do things in a safe order. Since |
24 |
>> we're starting over, this might even be made an error. |
25 |
> |
26 |
> I'm not really a fan of creating a new helper unless I have to; I would |
27 |
> rather modify checkpath's behaviour. |
28 |
> |
29 |
> The first stage of that modification would be to release a version that |
30 |
> outputs error messages, then convert the error messages to hard failures |
31 |
> in a later release. |
32 |
> |
33 |
> Is this reasonable? If we go this route, what should checkpath start |
34 |
> complaining about? |
35 |
|
36 |
/* |
37 |
Disclaimer: I'm not even sure that this difficult proposal will solve |
38 |
the problem. Moreover there may be legitimate things going on in some |
39 |
init scripts that I haven't accounted for. |
40 |
*/ |
41 |
|
42 |
The downside to keeping the name "checkpath" is that it makes it |
43 |
difficult to identify unfixed scripts. If we change the name, then "grep |
44 |
-rl checkpath" points them out for you; but if checkpath is modified, |
45 |
you have to install the package and attempt to start/stop/save/reload it |
46 |
and look for warnings. |
47 |
|
48 |
Aside from that, it sounds workable. I guess it should warn when either, |
49 |
|
50 |
1 checkpath is used to modify an existing path and actually changes it |
51 |
|
52 |
2 checkpath is used to create a path whose parent is not writable only |
53 |
by root and the OpenRC user (i.e. the heuristic you mentioned above) |
54 |
|
55 |
My rationale for those is as follows: |
56 |
|
57 |
1 Modifying existing paths in an automated fashion will never be safe |
58 |
due to the hardlink issue. If start_pre() creates both /foo |
59 |
and /foo/bar with owner "foo", then you can do that safely the first |
60 |
time around (when they're created), but the second time involves |
61 |
calling chown/chmod inside /foo which is writable by the "foo" user. |
62 |
|
63 |
If the service is restarted, /foo/bar might still exist, at which |
64 |
point we have to figure out what to do with it (assuming we don't |
65 |
blindly fix its permissions). I guess checkpath should check the |
66 |
existing permissions/ownership, and compare them to the desired |
67 |
ones? It's not an error if everything is the same, but if the init |
68 |
script wants something other than what's there, we should refuse to |
69 |
change things. |
70 |
|
71 |
2 Suppose again that we're creating both /foo and /foo/bar with owner |
72 |
"foo". If we run, |
73 |
|
74 |
checkpath --owner foo --directory /foo |
75 |
checkpath --owner foo --file /foo/bar |
76 |
|
77 |
then there's still an opportunity for the "foo" user to trick you in |
78 |
the short window where /foo exists but /foo/bar does not. Instead, |
79 |
we'd like to nudge the service script writer to do it some other |
80 |
way. Keeping in mind that we won't be able to modify the owner of |
81 |
/foo after /foo/bar is created (from item #1), this is the best that |
82 |
I can come up with: |
83 |
|
84 |
checkpath --owner foo --directory /foo |
85 |
su foo --command 'checkpath --file /foo/bar' |
86 |
|
87 |
That's safe because the "foo" user can only trick himself. |
88 |
|
89 |
The behavior of "su" isn't POSIX, but it's standard enough. If the |
90 |
construction above is common, maybe it makes sense to have checkpath |
91 |
drop privileges? So instead of, |
92 |
|
93 |
su foo --command 'checkpath --file /foo/bar' |
94 |
|
95 |
you could do, |
96 |
|
97 |
checkpath --as foo --file /foo/bar |
98 |
|
99 |
That would work because /foo is owned by "foo", and therefore |
100 |
writable by only the OpenRC user (now "foo") and root. |
101 |
|
102 |
|
103 |
This is all quite half-baked, so if anyone thinks that I've overlooked |
104 |
something obvious, you're probably not wrong. |