Skip to content

Commit 056ffb0

Browse files
committedJul 31, 2011
setcap: comment to help the user figure out why setcap is failing.
The file capabilities are not as expressive as process capabilities (for a reason - see the NOTES section of 'man 3 cap_set_file'). The effective bits on a file under linux are captured by a single boolean. As such attempting to partially set effective bits via the more fully expressive process capability representation (cap_from_text) sometimes yields an error. From now on, suggest that when the user attempts to do this and an error occurs, the error might be such a mismatch between effective and the other capability bits. Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
1 parent 616a03d commit 056ffb0

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed
 

‎progs/setcap.c

+25-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ static void usage(void)
2626

2727
static int read_caps(int quiet, const char *filename, char *buffer)
2828
{
29-
int i=MAXCAP;
29+
int i = MAXCAP;
3030

3131
if (!quiet) {
3232
fprintf(stderr, "Please enter caps for file [empty line to end]:\n");
@@ -170,10 +170,33 @@ int main(int argc, char **argv)
170170
}
171171
retval = cap_set_file(*++argv, cap_d);
172172
if (retval != 0) {
173+
int explained = 0;
174+
#ifdef linux
175+
cap_value_t cap;
176+
cap_flag_value_t per_state;
177+
178+
for (cap = 0;
179+
cap_get_flag(cap_d, cap, CAP_PERMITTED, &per_state) != -1;
180+
cap++) {
181+
cap_flag_value_t inh_state, eff_state;
182+
183+
cap_get_flag(cap_d, cap, CAP_INHERITABLE, &inh_state);
184+
cap_get_flag(cap_d, cap, CAP_EFFECTIVE, &eff_state);
185+
if ((inh_state | per_state) != eff_state) {
186+
fprintf(stderr, "NOTE: Under Linux, effective file capabilities must either be empty, or\n"
187+
" exactly match the union of selected permitted and inheritable bits.\n");
188+
explained = 1;
189+
break;
190+
}
191+
}
192+
#endif /* def linux */
193+
173194
fprintf(stderr,
174195
"Failed to set capabilities on file `%s' (%s)\n",
175196
argv[0], strerror(errno));
176-
usage();
197+
if (!explained) {
198+
usage();
199+
}
177200
}
178201
}
179202
if (cap_d) {

0 commit comments

Comments
 (0)
Please sign in to comment.