From: Darrick J. Wong Date: Thu, 28 Mar 2019 23:05:01 +0000 (-0500) Subject: xfs_io: don't walk off the end of argv in fzero_f X-Git-Tag: v5.0.0-rc1~46 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f019d5b7aa6ba04900147249bf98200a569fe8d9;p=thirdparty%2Fxfsprogs-dev.git xfs_io: don't walk off the end of argv in fzero_f The fzero_f function doesn't check that there are enough non-switch parameters to supply offset and length arguments to fallocate. As a result, we can walk off the end of the argv array and crash. A secondary problem is that we don't use getopt to detect the -k, which is not how most xfs_io commands work. Therefore, use getopt to detect the -k argument and rewire the offset and length interpretation code to check optind and use argv correctly. This bug is trivially reproduced by "xfs_io -c 'fzero -k 0' /some/file". Signed-off-by: Darrick J. Wong Reviewed-by: Eric Sandeen Signed-off-by: Eric Sandeen --- diff --git a/io/prealloc.c b/io/prealloc.c index 9a372bae9..6d452354e 100644 --- a/io/prealloc.c +++ b/io/prealloc.c @@ -285,18 +285,24 @@ fzero_f( { xfs_flock64_t segment; int mode = FALLOC_FL_ZERO_RANGE; - int index = 1; + int c; - if (strncmp(argv[index], "-k", 3) == 0) { - mode |= FALLOC_FL_KEEP_SIZE; - index++; + while ((c = getopt(argc, argv, "k")) != EOF) { + switch (c) { + case 'k': + mode |= FALLOC_FL_KEEP_SIZE; + break; + default: + command_usage(&fzero_cmd); + } } + if (optind != argc - 2) + return command_usage(&fzero_cmd); - if (!offset_length(argv[index], argv[index + 1], &segment)) + if (!offset_length(argv[optind], argv[optind + 1], &segment)) return 0; - if (fallocate(file->fd, mode, - segment.l_start, segment.l_len)) { + if (fallocate(file->fd, mode, segment.l_start, segment.l_len)) { perror("fallocate"); return 0; }