]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_io: don't walk off the end of argv in fzero_f
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 28 Mar 2019 23:05:01 +0000 (18:05 -0500)
committerEric Sandeen <sandeen@redhat.com>
Thu, 28 Mar 2019 23:05:01 +0000 (18:05 -0500)
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 <darrick.wong@oracle.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
io/prealloc.c

index 9a372bae96213c32c5a1b4c263a91fdb677fbbe4..6d452354ee458fdf1f60ccdc3f54063c65e8bc63 100644 (file)
@@ -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;
        }