Add libfuse util strtol wrapper
authorJoanne Koong <joannelkoong@gmail.com>
Mon, 7 Oct 2024 20:37:20 +0000 (13:37 -0700)
committerBernd Schubert <bernd.schubert@fastmail.fm>
Fri, 11 Oct 2024 11:15:38 +0000 (13:15 +0200)
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
lib/fuse_lowlevel.c
lib/meson.build
lib/mount_bsd.c
lib/util.c [new file with mode: 0644]
lib/util.h [new file with mode: 0644]
util/fusermount.c
util/meson.build

index ecf8af81bca4cf0f58b7d909514c1232e53897bf..075ac2e02d7b945c189d33beda58237e9fc0178a 100644 (file)
@@ -13,6 +13,7 @@
 #include "fuse_misc.h"
 #include "fuse_kernel.h"
 #include "fuse_i.h"
+#include "util.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -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);
index a505552f59a55af44d8a6c7e6e7eab072cdee0ab..ef1cda5606f66a075ec8fa68e609f217239bbdae 100644 (file)
@@ -17,6 +17,7 @@
 #include "fuse_opt.h"
 #include "fuse_misc.h"
 #include "mount_util.h"
+#include "util.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -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)
index 1822ce0c209c15fe397ad6503a32aaf332b2fd5a..34dd60772387194a13825c2137384a68d12b6dad 100644 (file)
@@ -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' ]
index c9669ae4bb1a6177e25e336cf2ca10cd62493fcc..1863c49c6ff5add486b625b8603285a263f15c15 100644 (file)
@@ -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 (file)
index 0000000..a529d38
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+#include <errno.h>
+
+#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 (file)
index 0000000..0a01711
--- /dev/null
@@ -0,0 +1 @@
+int libfuse_strtol(const char *str, long *res);
index 852834298315be305225d1da6beddb0d0e5f60f7..b87d8bb70703e7986c627b40a2c826ccbdb11ac4 100644 (file)
@@ -10,6 +10,7 @@
 #define _GNU_SOURCE /* for clone and strchrnul */
 #include "fuse_config.h"
 #include "mount_util.h"
+#include "util.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -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;
                }
index 01c92f0b925fcfe3178a5394a24dd4e670bf8ff7..0e4b1cce95377e73af7dc45655a7088315497ddb 100644 (file)
@@ -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'),