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.
This commit is contained in:
Joanne Koong 2024-10-07 13:37:20 -07:00 committed by Bernd Schubert
parent 55eb214db9
commit 535808c4d9
8 changed files with 66 additions and 21 deletions

View File

@ -13,6 +13,7 @@
#include "fuse_misc.h" #include "fuse_misc.h"
#include "fuse_kernel.h" #include "fuse_kernel.h"
#include "fuse_i.h" #include "fuse_i.h"
#include "util.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.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); pthread_attr_init(&attr);
stack_size = getenv(ENVNAME_THREAD_STACK); stack_size = getenv(ENVNAME_THREAD_STACK);
if (stack_size && pthread_attr_setstacksize(&attr, atoi(stack_size))) if (stack_size) {
fuse_log(FUSE_LOG_ERR, "fuse: invalid stack size: %s\n", 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 */ /* Disallow signal reception in worker threads */
sigemptyset(&newset); sigemptyset(&newset);

View File

@ -17,6 +17,7 @@
#include "fuse_opt.h" #include "fuse_opt.h"
#include "fuse_misc.h" #include "fuse_misc.h"
#include "mount_util.h" #include "mount_util.h"
#include "util.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.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) static int grow_pipe_to_max(int pipefd)
{ {
int max;
int res; int res;
int maxfd; long max;
long maxfd;
char buf[32]; char buf[32];
maxfd = open("/proc/sys/fs/pipe-max-size", O_RDONLY); maxfd = open("/proc/sys/fs/pipe-max-size", O_RDONLY);
@ -685,7 +686,9 @@ static int grow_pipe_to_max(int pipefd)
close(maxfd); close(maxfd);
buf[res] = '\0'; buf[res] = '\0';
max = atoi(buf); res = libfuse_strtol(buf, &max);
if (res)
return res;
res = fcntl(pipefd, F_SETPIPE_SZ, max); res = fcntl(pipefd, F_SETPIPE_SZ, max);
if (res < 0) if (res < 0)
return -errno; return -errno;
@ -2907,8 +2910,9 @@ static void fuse_ll_pipe_destructor(void *data)
static unsigned int get_max_pages(void) static unsigned int get_max_pages(void)
{ {
char buf[32]; char buf[32];
int res; long res;
int fd; int fd;
int err;
fd = open("/proc/sys/fs/fuse/max_pages_limit", O_RDONLY); fd = open("/proc/sys/fs/fuse/max_pages_limit", O_RDONLY);
if (fd < 0) if (fd < 0)
@ -2923,8 +2927,8 @@ static unsigned int get_max_pages(void)
buf[res] = '\0'; buf[res] = '\0';
res = strtol(buf, NULL, 10); err = libfuse_strtol(buf, &res);
return res < 0 ? FUSE_DEFAULT_MAX_PAGES_LIMIT : res; return err ? FUSE_DEFAULT_MAX_PAGES_LIMIT : res;
} }
int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf) int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf)

View 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_lowlevel.c', 'fuse_misc.h', 'fuse_opt.c',
'fuse_signals.c', 'buffer.c', 'cuse_lowlevel.c', 'fuse_signals.c', 'buffer.c', 'cuse_lowlevel.c',
'helper.c', 'modules/subdir.c', 'mount_util.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') if host_machine.system().startswith('linux')
libfuse_sources += [ 'mount.c' ] libfuse_sources += [ 'mount.c' ]

View File

@ -155,22 +155,17 @@ static int fuse_mount_core(const char *mountpoint, const char *opts)
char *fdnam, *dev; char *fdnam, *dev;
pid_t pid, cpid; pid_t pid, cpid;
int status; int status;
int err;
fdnam = getenv("FUSE_DEV_FD"); fdnam = getenv("FUSE_DEV_FD");
if (fdnam) { if (fdnam) {
char *ep; err = libfuse_strtol(fdnam, &fd);
if (err) {
fd = strtol(fdnam, &ep, 10);
if (*ep != '\0') {
fuse_log(FUSE_LOG_ERR, "invalid value given in FUSE_DEV_FD\n"); fuse_log(FUSE_LOG_ERR, "invalid value given in FUSE_DEV_FD\n");
return -1; return -1;
} }
if (fd < 0)
return -1;
goto mount; goto mount;
} }

27
lib/util.c Normal file
View File

@ -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;
}

1
lib/util.h Normal file
View File

@ -0,0 +1 @@
int libfuse_strtol(const char *str, long *res);

View File

@ -10,6 +10,7 @@
#define _GNU_SOURCE /* for clone and strchrnul */ #define _GNU_SOURCE /* for clone and strchrnul */
#include "fuse_config.h" #include "fuse_config.h"
#include "mount_util.h" #include "mount_util.h"
#include "util.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -1500,7 +1501,7 @@ int main(int argc, char *argv[])
static int lazy = 0; static int lazy = 0;
static int quiet = 0; static int quiet = 0;
char *commfd = NULL; char *commfd = NULL;
int cfd; long cfd;
const char *opts = ""; const char *opts = "";
const char *type = NULL; const char *type = NULL;
int setup_auto_unmount_only = 0; int setup_auto_unmount_only = 0;
@ -1604,13 +1605,20 @@ int main(int argc, char *argv[])
goto err_out; 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; struct stat statbuf;
fstat(cfd, &statbuf); fstat(cfd, &statbuf);
if(!S_ISSOCK(statbuf.st_mode)) { if(!S_ISSOCK(statbuf.st_mode)) {
fprintf(stderr, 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); progname, cfd);
goto err_out; goto err_out;
} }

View File

@ -1,6 +1,6 @@
fuseconf_path = join_paths(get_option('prefix'), get_option('sysconfdir'), 'fuse.conf') 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, include_directories: include_dirs,
install: true, install: true,
install_dir: get_option('bindir'), install_dir: get_option('bindir'),