From 535808c4d93e4637577aa17bf8413a41920dd2d8 Mon Sep 17 00:00:00 2001 From: Joanne Koong Date: Mon, 7 Oct 2024 13:37:20 -0700 Subject: [PATCH] Add libfuse util strtol wrapper Add a wrapper around strtol for more rigorous error checking and convert uses of atoi and strtol to use this instead. --- lib/fuse_loop_mt.c | 14 ++++++++++++-- lib/fuse_lowlevel.c | 16 ++++++++++------ lib/meson.build | 2 +- lib/mount_bsd.c | 11 +++-------- lib/util.c | 27 +++++++++++++++++++++++++++ lib/util.h | 1 + util/fusermount.c | 14 +++++++++++--- util/meson.build | 2 +- 8 files changed, 66 insertions(+), 21 deletions(-) create mode 100644 lib/util.c create mode 100644 lib/util.h diff --git a/lib/fuse_loop_mt.c b/lib/fuse_loop_mt.c index ecf8af8..075ac2e 100644 --- a/lib/fuse_loop_mt.c +++ b/lib/fuse_loop_mt.c @@ -13,6 +13,7 @@ #include "fuse_misc.h" #include "fuse_kernel.h" #include "fuse_i.h" +#include "util.h" #include #include @@ -220,8 +221,17 @@ int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg) */ pthread_attr_init(&attr); stack_size = getenv(ENVNAME_THREAD_STACK); - if (stack_size && pthread_attr_setstacksize(&attr, atoi(stack_size))) - fuse_log(FUSE_LOG_ERR, "fuse: invalid stack size: %s\n", stack_size); + if (stack_size) { + long size; + + res = libfuse_strtol(stack_size, &size); + if (res) + fuse_log(FUSE_LOG_ERR, "fuse: invalid stack size: %s\n", + stack_size); + else if (pthread_attr_setstacksize(&attr, size)) + fuse_log(FUSE_LOG_ERR, "fuse: could not set stack size: %ld\n", + size); + } /* Disallow signal reception in worker threads */ sigemptyset(&newset); diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index a505552..ef1cda5 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -17,6 +17,7 @@ #include "fuse_opt.h" #include "fuse_misc.h" #include "mount_util.h" +#include "util.h" #include #include @@ -665,9 +666,9 @@ static int read_back(int fd, char *buf, size_t len) static int grow_pipe_to_max(int pipefd) { - int max; int res; - int maxfd; + long max; + long maxfd; char buf[32]; maxfd = open("/proc/sys/fs/pipe-max-size", O_RDONLY); @@ -685,7 +686,9 @@ static int grow_pipe_to_max(int pipefd) close(maxfd); buf[res] = '\0'; - max = atoi(buf); + res = libfuse_strtol(buf, &max); + if (res) + return res; res = fcntl(pipefd, F_SETPIPE_SZ, max); if (res < 0) return -errno; @@ -2907,8 +2910,9 @@ static void fuse_ll_pipe_destructor(void *data) static unsigned int get_max_pages(void) { char buf[32]; - int res; + long res; int fd; + int err; fd = open("/proc/sys/fs/fuse/max_pages_limit", O_RDONLY); if (fd < 0) @@ -2923,8 +2927,8 @@ static unsigned int get_max_pages(void) buf[res] = '\0'; - res = strtol(buf, NULL, 10); - return res < 0 ? FUSE_DEFAULT_MAX_PAGES_LIMIT : res; + err = libfuse_strtol(buf, &res); + return err ? FUSE_DEFAULT_MAX_PAGES_LIMIT : res; } int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf) diff --git a/lib/meson.build b/lib/meson.build index 1822ce0..34dd607 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -2,7 +2,7 @@ libfuse_sources = ['fuse.c', 'fuse_i.h', 'fuse_loop.c', 'fuse_loop_mt.c', 'fuse_lowlevel.c', 'fuse_misc.h', 'fuse_opt.c', 'fuse_signals.c', 'buffer.c', 'cuse_lowlevel.c', 'helper.c', 'modules/subdir.c', 'mount_util.c', - 'fuse_log.c', 'compat.c' ] + 'fuse_log.c', 'compat.c', 'util.c', 'util.h' ] if host_machine.system().startswith('linux') libfuse_sources += [ 'mount.c' ] diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c index c9669ae..1863c49 100644 --- a/lib/mount_bsd.c +++ b/lib/mount_bsd.c @@ -155,22 +155,17 @@ static int fuse_mount_core(const char *mountpoint, const char *opts) char *fdnam, *dev; pid_t pid, cpid; int status; + int err; fdnam = getenv("FUSE_DEV_FD"); if (fdnam) { - char *ep; - - fd = strtol(fdnam, &ep, 10); - - if (*ep != '\0') { + err = libfuse_strtol(fdnam, &fd); + if (err) { fuse_log(FUSE_LOG_ERR, "invalid value given in FUSE_DEV_FD\n"); return -1; } - if (fd < 0) - return -1; - goto mount; } diff --git a/lib/util.c b/lib/util.c new file mode 100644 index 0000000..a529d38 --- /dev/null +++ b/lib/util.c @@ -0,0 +1,27 @@ +#include +#include + +#include "util.h" + +int libfuse_strtol(const char *str, long *res) +{ + char *endptr; + int base = 10; + long val; + + errno = 0; + + if (!str) + return -EINVAL; + + val = strtol(str, &endptr, base); + + if (errno) + return -errno; + + if (endptr == str || *endptr != '\0') + return -EINVAL; + + *res = val; + return 0; +} diff --git a/lib/util.h b/lib/util.h new file mode 100644 index 0000000..0a01711 --- /dev/null +++ b/lib/util.h @@ -0,0 +1 @@ +int libfuse_strtol(const char *str, long *res); diff --git a/util/fusermount.c b/util/fusermount.c index 8528342..b87d8bb 100644 --- a/util/fusermount.c +++ b/util/fusermount.c @@ -10,6 +10,7 @@ #define _GNU_SOURCE /* for clone and strchrnul */ #include "fuse_config.h" #include "mount_util.h" +#include "util.h" #include #include @@ -1500,7 +1501,7 @@ int main(int argc, char *argv[]) static int lazy = 0; static int quiet = 0; char *commfd = NULL; - int cfd; + long cfd; const char *opts = ""; const char *type = NULL; int setup_auto_unmount_only = 0; @@ -1604,13 +1605,20 @@ int main(int argc, char *argv[]) goto err_out; } - cfd = atoi(commfd); + res = libfuse_strtol(commfd, &cfd); + if (res) { + fprintf(stderr, + "%s: invalid _FUSE_COMMFD: %s\n", + progname, commfd); + goto err_out; + + } { struct stat statbuf; fstat(cfd, &statbuf); if(!S_ISSOCK(statbuf.st_mode)) { fprintf(stderr, - "%s: file descriptor %i is not a socket, can't send fuse fd\n", + "%s: file descriptor %li is not a socket, can't send fuse fd\n", progname, cfd); goto err_out; } diff --git a/util/meson.build b/util/meson.build index 01c92f0..0e4b1cc 100644 --- a/util/meson.build +++ b/util/meson.build @@ -1,6 +1,6 @@ fuseconf_path = join_paths(get_option('prefix'), get_option('sysconfdir'), 'fuse.conf') -executable('fusermount3', ['fusermount.c', '../lib/mount_util.c'], +executable('fusermount3', ['fusermount.c', '../lib/mount_util.c', '../lib/util.c'], include_directories: include_dirs, install: true, install_dir: get_option('bindir'),