Skip to content

Commit 3005c09

Browse files
committed
virtiofsd: Allow addition or removal of capabilities
Allow capabilities to be added or removed from the allowed set for the daemon; e.g. default: CapPrm: 00000000880000df CapEff: 00000000880000df -o modcaps=+sys_admin CapPrm: 00000000882000df CapEff: 00000000882000df -o modcaps=+sys_admin:-chown CapPrm: 00000000882000de CapEff: 00000000882000de Signed-off-by: Dr. David Alan Gilbert <[email protected]> Message-Id: <[email protected]> Acked-by: Vivek Goyal <[email protected]> Reviewed-by: Stefan Hajnoczi <[email protected]> Signed-off-by: Dr. David Alan Gilbert <[email protected]>
1 parent 55b22a6 commit 3005c09

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

docs/tools/virtiofsd.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ Options
5454
* flock|no_flock -
5555
Enable/disable flock. The default is ``no_flock``.
5656

57+
* modcaps=CAPLIST
58+
Modify the list of capabilities allowed; CAPLIST is a colon separated
59+
list of capabilities, each preceded by either + or -, e.g.
60+
''+sys_admin:-chown''.
61+
5762
* log_level=LEVEL -
5863
Print only log messages matching LEVEL or more severe. LEVEL is one of
5964
``err``, ``warn``, ``info``, or ``debug``. The default is ``info``.

tools/virtiofsd/helper.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ void fuse_cmdline_help(void)
174174
" default: no_writeback\n"
175175
" -o xattr|no_xattr enable/disable xattr\n"
176176
" default: no_xattr\n"
177+
" -o modcaps=CAPLIST Modify the list of capabilities\n"
178+
" e.g. -o modcaps=+sys_admin:-chown\n"
177179
" --rlimit-nofile=<num> set maximum number of file descriptors\n"
178180
" (0 leaves rlimit unchanged)\n"
179181
" default: min(1000000, fs.file-max - 16384)\n"

tools/virtiofsd/passthrough_ll.c

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ struct lo_data {
145145
int posix_lock;
146146
int xattr;
147147
char *source;
148+
char *modcaps;
148149
double timeout;
149150
int cache;
150151
int timeout_set;
@@ -170,6 +171,7 @@ static const struct fuse_opt lo_opts[] = {
170171
{ "no_posix_lock", offsetof(struct lo_data, posix_lock), 0 },
171172
{ "xattr", offsetof(struct lo_data, xattr), 1 },
172173
{ "no_xattr", offsetof(struct lo_data, xattr), 0 },
174+
{ "modcaps=%s", offsetof(struct lo_data, modcaps), 0 },
173175
{ "timeout=%lf", offsetof(struct lo_data, timeout), 0 },
174176
{ "timeout=", offsetof(struct lo_data, timeout_set), 1 },
175177
{ "cache=none", offsetof(struct lo_data, cache), CACHE_NONE },
@@ -2570,9 +2572,11 @@ static void setup_mounts(const char *source)
25702572

25712573
/*
25722574
* Only keep whitelisted capabilities that are needed for file system operation
2575+
* The (possibly NULL) modcaps_in string passed in is free'd before exit.
25732576
*/
2574-
static void setup_capabilities(void)
2577+
static void setup_capabilities(char *modcaps_in)
25752578
{
2579+
char *modcaps = modcaps_in;
25762580
pthread_mutex_lock(&cap.mutex);
25772581
capng_restore_state(&cap.saved);
25782582

@@ -2604,6 +2608,51 @@ static void setup_capabilities(void)
26042608
exit(1);
26052609
}
26062610

2611+
/*
2612+
* The modcaps option is a colon separated list of caps,
2613+
* each preceded by either + or -.
2614+
*/
2615+
while (modcaps) {
2616+
capng_act_t action;
2617+
int cap;
2618+
2619+
char *next = strchr(modcaps, ':');
2620+
if (next) {
2621+
*next = '\0';
2622+
next++;
2623+
}
2624+
2625+
switch (modcaps[0]) {
2626+
case '+':
2627+
action = CAPNG_ADD;
2628+
break;
2629+
2630+
case '-':
2631+
action = CAPNG_DROP;
2632+
break;
2633+
2634+
default:
2635+
fuse_log(FUSE_LOG_ERR,
2636+
"%s: Expecting '+'/'-' in modcaps but found '%c'\n",
2637+
__func__, modcaps[0]);
2638+
exit(1);
2639+
}
2640+
cap = capng_name_to_capability(modcaps + 1);
2641+
if (cap < 0) {
2642+
fuse_log(FUSE_LOG_ERR, "%s: Unknown capability '%s'\n", __func__,
2643+
modcaps);
2644+
exit(1);
2645+
}
2646+
if (capng_update(action, CAPNG_PERMITTED | CAPNG_EFFECTIVE, cap)) {
2647+
fuse_log(FUSE_LOG_ERR, "%s: capng_update failed for '%s'\n",
2648+
__func__, modcaps);
2649+
exit(1);
2650+
}
2651+
2652+
modcaps = next;
2653+
}
2654+
g_free(modcaps_in);
2655+
26072656
if (capng_apply(CAPNG_SELECT_BOTH)) {
26082657
fuse_log(FUSE_LOG_ERR, "%s: capng_apply failed\n", __func__);
26092658
exit(1);
@@ -2627,7 +2676,7 @@ static void setup_sandbox(struct lo_data *lo, struct fuse_session *se,
26272676
setup_namespaces(lo, se);
26282677
setup_mounts(lo->source);
26292678
setup_seccomp(enable_syslog);
2630-
setup_capabilities();
2679+
setup_capabilities(g_strdup(lo->modcaps));
26312680
}
26322681

26332682
/* Set the maximum number of open file descriptors */

0 commit comments

Comments
 (0)