From b3ab365fda1a65f2c3535cda15de885bfa9de814 Mon Sep 17 00:00:00 2001 From: Nikolaus Rath Date: Mon, 24 Oct 2016 20:31:29 -0700 Subject: [PATCH] fuse_session_new(): don't accept empty argv, check argv[0] This should help avoid people to accidentally put options into argv[0]. Fixes #100. --- ChangeLog.rst | 4 ++++ include/fuse.h | 18 +++++++++++++----- include/fuse_lowlevel.h | 6 ++++++ lib/fuse_lowlevel.c | 12 +++++++++++- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/ChangeLog.rst b/ChangeLog.rst index e614e6b..2019325 100644 --- a/ChangeLog.rst +++ b/ChangeLog.rst @@ -1,6 +1,10 @@ Unreleased Changes ================== +* Documentation: clarified that the fuse_argv structure that is passed + to `fuse_new()` and `fuse_lowlevel_new()` must always contain at + least one element. + * The high-level init() handler now receives an additional struct fuse_config pointer that can be used to adjust high-level API specific configuration options. diff --git a/include/fuse.h b/include/fuse.h index e8ff936..312818e 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -748,11 +748,13 @@ struct fuse_context { * fuse_main() accepts all options that can be passed to * fuse_parse_cmdline(), fuse_new(), or fuse_session_new(). * - * Normally, fuse_main() includes a basic ``usage: `` message in the - * --help output. However, if argv[0] is an empty string, the usage - * message is suppressed. This can be used by file systems to print - * their own usage line first. See hello.c for an example of how to do - * this. + * Option parsing skips argv[0], which is assumed to contain the + * program name. This element must always be present and is used to + * construct a basic ``usage: `` message for the --help + * output. argv[0] may also be set to the empty string. In this case + * the usage message is suppressed. This can be used by file systems + * to print their own usage line first. See hello.c for an example of + * how to do this. * * Note: this is currently implemented as a macro. * @@ -785,6 +787,12 @@ struct fuse_context { * If the --help option is specified, the function writes a help text * to stdout and returns NULL. * + * Option parsing skips argv[0], which is assumed to contain the + * program name. This element must always be present and is used to + * construct a basic ``usage: `` message for the --help output. If + * argv[0] is set to the empty string, no usage message is included in + * the --help output. + * * If an unknown option is passed in, an error message is written to * stderr and the function returns NULL. * diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h index 8ec95b5..e6f95a9 100644 --- a/include/fuse_lowlevel.h +++ b/include/fuse_lowlevel.h @@ -1655,6 +1655,12 @@ int fuse_parse_cmdline(struct fuse_args *args, * If not all options are known, an error message is written to stderr * and the function returns NULL. * + * Option parsing skips argv[0], which is assumed to contain the + * program name. To prevent accidentially passing an option in + * argv[0], this element must always be present (even if no options + * are specified). It may be set to the empty string ('\0') if no + * reasonable value can be provided. + * * @param args argument vector * @param op the (low-level) filesystem operations * @param op_size sizeof(struct fuse_lowlevel_ops) diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 8889d2d..3aa12de 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -2739,6 +2739,11 @@ struct fuse_session *fuse_session_new(struct fuse_args *args, op_size = sizeof(struct fuse_lowlevel_ops); } + if (args->argc == 0) { + fprintf(stderr, "fuse: empty argv passed to fuse_session_new().\n"); + return NULL; + } + se = (struct fuse_session *) calloc(1, sizeof(struct fuse_session)); if (se == NULL) { fprintf(stderr, "fuse: failed to allocate fuse object\n"); @@ -2754,7 +2759,12 @@ struct fuse_session *fuse_session_new(struct fuse_args *args, goto out2; if(fuse_opt_parse(args, se, fuse_ll_opts, NULL) == -1) goto out3; - if (args->argc != 1) { + + if(args->argc == 1 && + args->argv[0][0] == '-') { + fprintf(stderr, "fuse: warning: argv[0] looks like an option, but " + "will be ignored\n"); + } else if (args->argc != 1) { int i; fprintf(stderr, "fuse: unknown option(s): `"); for(i = 1; i < args->argc-1; i++) -- 2.30.2