1 |
On Sat, Mar 05, 2011 at 02:24:22PM +0100, Constanze Hausner wrote: |
2 |
> fcaps() { |
3 |
> debug-print-function ${FUNCNAME} "$@" |
4 |
> debug-print "${FUNCNAME}: Trying to set capabilities for ${4}" |
5 |
> local uid_gid=$1 |
6 |
> local perms=$2 |
7 |
> export fallbackFileMode=$perms |
8 |
> local capset=$3 |
9 |
> local path=$4 |
10 |
|
11 |
That export of fallbackFileMode looks pointless... clarify please. |
12 |
Also, your arg count checking here means it's going to throw some |
13 |
weird ass errors if people invoke it incorrectly. You likely want a |
14 |
|
15 |
[ $# -ne 4 ] && die "wrong arg count" |
16 |
|
17 |
thrown in there.. |
18 |
|
19 |
|
20 |
> if [ $# -eq 5 ]; then |
21 |
> local set_mode=$5 |
22 |
> else |
23 |
> debug-print "${FUNCNAME}: no set-mode provided, setting it to ep" |
24 |
> #if there is no set_mode provided, it is set to true |
25 |
> local set_mode=1 |
26 |
> fi |
27 |
> |
28 |
> #set owner/group |
29 |
> debug-print "${FUNCNAME}: setting owner and group to ${uid_gid}" |
30 |
> chown $uid_gid $path |
31 |
> if [ $? -ne 0 ]; then |
32 |
> eerror "chown "$uid_gid" "$path" failed." |
33 |
> return 2 |
34 |
> fi |
35 |
> |
36 |
> #set file-mode including suid |
37 |
> debug-print "${FUNCNAME}: setting file-mode ${perms}, including suid" |
38 |
> chmod $perms $path |
39 |
|
40 |
Arbitrary/user-controlled path's always need to be quoted... |
41 |
|
42 |
> if [ $? -ne 0 ]; then |
43 |
> eerror "chmod "$perms" "$path" failed." |
44 |
> return 3 |
45 |
> fi |
46 |
> |
47 |
> #if filecaps is not enabled all is done |
48 |
> use !filecaps && return 0 |
49 |
> |
50 |
> #if libcap is not installed caps cannot be set |
51 |
> if [ ! -f "/sbin/setcap" ]; then |
52 |
> debug-print "${FUNCNAME}: libcap not installed, could not set caps" |
53 |
> return 4 |
54 |
> fi |
55 |
> |
56 |
> #Check for set mode |
57 |
> if [ $set_mode -eq 1 ]; then |
58 |
> debug-print "${FUNCNAME}: set-mode = ep" |
59 |
> local sets="=ep" |
60 |
> else |
61 |
> debug-print "${FUNCNAME}: set-mode = ei" |
62 |
> local sets="=ei" |
63 |
> fi |
64 |
|
65 |
Shift this into the initial arg processing; eliminates the need for |
66 |
set_mode and is simpler to follow. |
67 |
|
68 |
> |
69 |
> #set the capability |
70 |
> debug-print "${FUNCNAME}: setting capabilities" |
71 |
|
72 |
lay off the debug-print's a bit... |
73 |
|
74 |
> setcap "$capset""$sets" "$path" &> /dev/null |
75 |
> |
76 |
> #check if the capabilitiy got set correctly |
77 |
> debug-print "${FUNCNAME}: checking capabilities" |
78 |
> setcap -v "$capset""$sets" "$path" &> /dev/null |
79 |
> |
80 |
> local res=$? |
81 |
> |
82 |
> #if caps could be set, remove suid-bit |
83 |
> if [ $res -eq 0 ]; then |
84 |
> debug-print "${FUNCNAME}: caps were set, removing suid-bit" |
85 |
> chmod -s $path |
86 |
> else |
87 |
> debug-print "${FUNCNAME}: caps could not be set" |
88 |
> ewarn "setcap "$capset" "$path" failed." |
89 |
> ewarn "Check your kernel and filesystem." |
90 |
> ewarn "Fallback file-mode was set." |
91 |
> fi |
92 |
> |
93 |
> return $res |
94 |
> } |
95 |
|
96 |
I'd take a different approach here; this code basically assumes that |
97 |
the PM knows of it- note the chmod -s. The use flag protection you |
98 |
tried adding, without some profile hacks, is user modifiable- meaning |
99 |
users can flip it on even if the PM doesn't support it. |
100 |
|
101 |
Or consider that the code above is purely doing it's thing during the |
102 |
install phase, specifically against whatever filesystem is used for |
103 |
building- while capabilities might be able to be set there, it's |
104 |
possible the final merge location won't support it. End result of |
105 |
that is you'll get a setuid stripped binary merged to the |
106 |
livefs lacking the caps- borkage. Or consider the inverse- the |
107 |
buildroot can't do capabilities, but the livefs could. You get the |
108 |
idea. |
109 |
|
110 |
Instead, write the code so the PM has to export a marker in some |
111 |
fashion to explicitly state "yes, I can do capabilities"- I'm |
112 |
specifically suggestining checking for a callback function exposed to |
113 |
the env. |
114 |
|
115 |
If that function isn't there, then the PM can't do it- end of story. |
116 |
If it is, the PM takes the args and will try to apply the |
117 |
capabilities at the correct time- stripping setuid/setgid if it |
118 |
succeeds. |
119 |
|
120 |
Please go that route; and please do not stick "portage" into the |
121 |
function name, something generic we can use for a later EAPI is |
122 |
better. |
123 |
|
124 |
Implementing it as I suggested has the nice side affect of not being |
125 |
limited by PMS also, although it's an approach that still requires |
126 |
planning for compatibility. |
127 |
|
128 |
Thanks- |
129 |
~brian |