mirror of
https://github.com/libfuse/libfuse.git
synced 2026-07-07 14:47:41 +08:00
lib: use quote-aware tokenizer for mount option parsing
The strtok_r(opts, ",", ...) based option splitter does not understand double-quoted values. SELinux MLS labels can contain commas inside quotes (e.g., context="system_u:object_r:root_t:s0:c0,c1"), which would be incorrectly split into separate tokens. Replace strtok_r with a quote-aware next_mount_opt() helper that skips commas inside double-quoted regions. Signed-off-by: Jingbo Xu <jingbo.xu@linux.alibaba.com> Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com>
This commit is contained in:
committed by
Bernd Schubert
parent
24d40b2a7c
commit
9e22f4e59e
+38
-4
@@ -263,11 +263,44 @@ static int is_mtab_only_opt(const char *opt)
|
||||
strcmp(opt, "rw") == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Example: parsing rw,fd=7,context="u:r:t,s0"
|
||||
*
|
||||
* call 3 -> "context=\"u:r:t,s0\"" (comma inside quotes kept, not split)
|
||||
* call 4 -> NULL
|
||||
*/
|
||||
static char *next_mount_opt(char **cursor)
|
||||
{
|
||||
char *opt_start;
|
||||
char *scan;
|
||||
int in_quote = 0;
|
||||
|
||||
if (!*cursor || !**cursor)
|
||||
return NULL;
|
||||
|
||||
opt_start = *cursor;
|
||||
for (scan = opt_start; *scan; scan++) {
|
||||
if (*scan == '"')
|
||||
in_quote = !in_quote;
|
||||
else if (*scan == ',' && !in_quote)
|
||||
break;
|
||||
}
|
||||
|
||||
if (*scan == ',') {
|
||||
*scan = '\0';
|
||||
*cursor = scan + 1;
|
||||
} else {
|
||||
*cursor = scan;
|
||||
}
|
||||
|
||||
return opt_start;
|
||||
}
|
||||
|
||||
int apply_fsconfig_mount_opts(int fsfd, const char *opts)
|
||||
{
|
||||
char *opts_copy;
|
||||
char *pos;
|
||||
char *opt;
|
||||
char *saveptr;
|
||||
int res;
|
||||
|
||||
if (!opts || !*opts)
|
||||
@@ -279,8 +312,10 @@ int apply_fsconfig_mount_opts(int fsfd, const char *opts)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
opt = strtok_r(opts_copy, ",", &saveptr);
|
||||
while (opt) {
|
||||
pos = opts_copy;
|
||||
while ((opt = next_mount_opt(&pos)) != NULL) {
|
||||
if (!*opt)
|
||||
continue;
|
||||
/*
|
||||
* Skip mount attributes, they're handled by fsmount()
|
||||
* not fsconfig().
|
||||
@@ -303,7 +338,6 @@ int apply_fsconfig_mount_opts(int fsfd, const char *opts)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
opt = strtok_r(NULL, ",", &saveptr);
|
||||
}
|
||||
|
||||
free(opts_copy);
|
||||
|
||||
Reference in New Issue
Block a user