torture/ioctl: add range overflow QAR test
authorDavid Disseldorp <ddiss@samba.org>
Mon, 9 Mar 2015 15:21:24 +0000 (16:21 +0100)
committerJeremy Allison <jra@samba.org>
Mon, 9 Mar 2015 23:02:18 +0000 (00:02 +0100)
Issue a QAR request with an offset and length that generate an integer
(uint64_t) overflow when summed together. This should result in an
NT_STATUS_INVALID_PARAMETER response, as confirmed against Windows
Server 2012 & 2008.

Signed-off-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Tue Mar 10 00:02:18 CET 2015 on sn-devel-104

source4/torture/smb2/ioctl.c

index 5067d52016c88712d67c3f53a5efc2b8e6532a67..43f98be1950d4cce4dd220c6273330b60b267290 100644 (file)
@@ -4596,6 +4596,55 @@ static bool test_ioctl_sparse_qar_multi(struct torture_context *torture,
        return true;
 }
 
+static bool test_ioctl_sparse_qar_overflow(struct torture_context *torture,
+                                          struct smb2_tree *tree)
+{
+       struct smb2_handle fh;
+       union smb_ioctl ioctl;
+       struct file_alloced_range_buf far_buf;
+       NTSTATUS status;
+       enum ndr_err_code ndr_ret;
+       TALLOC_CTX *tmp_ctx = talloc_new(tree);
+       bool ok;
+
+       ok = test_setup_create_fill(torture, tree, tmp_ctx,
+                                   FNAME, &fh, 1024, SEC_RIGHTS_FILE_ALL,
+                                   FILE_ATTRIBUTE_NORMAL);
+       torture_assert(torture, ok, "setup file");
+
+       status = test_ioctl_sparse_fs_supported(torture, tree, tmp_ctx, &fh,
+                                               &ok);
+       torture_assert_ntstatus_ok(torture, status, "SMB2_GETINFO_FS");
+       if (!ok) {
+               smb2_util_close(tree, fh);
+               torture_skip(torture, "Sparse files not supported\n");
+       }
+
+       /* no allocated ranges, no space for range response, should pass */
+       ZERO_STRUCT(ioctl);
+       ioctl.smb2.level = RAW_IOCTL_SMB2;
+       ioctl.smb2.in.file.handle = fh;
+       ioctl.smb2.in.function = FSCTL_QUERY_ALLOCATED_RANGES;
+       ioctl.smb2.in.max_response_size = 1024;
+       ioctl.smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;
+
+       /* off + length wraps around to 511 */
+       far_buf.file_off = 512;
+       far_buf.len = (uint64_t)0xffffffffffffffff;
+       ndr_ret = ndr_push_struct_blob(&ioctl.smb2.in.out, tmp_ctx,
+                                      &far_buf,
+                       (ndr_push_flags_fn_t)ndr_push_file_alloced_range_buf);
+       torture_assert_ndr_success(torture, ndr_ret, "push far ndr buf");
+
+       status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
+       torture_assert_ntstatus_equal(torture, status,
+                                     NT_STATUS_INVALID_PARAMETER,
+                                     "FSCTL_QUERY_ALLOCATED_RANGES overflow");
+
+       return true;
+}
+
+
 /*
  * basic testing of SMB2 ioctls
  */
@@ -4695,6 +4744,8 @@ struct torture_suite *torture_smb2_ioctl_init(void)
                                     test_ioctl_sparse_qar_ob1);
        torture_suite_add_1smb2_test(suite, "sparse_qar_multi",
                                     test_ioctl_sparse_qar_multi);
+       torture_suite_add_1smb2_test(suite, "sparse_qar_overflow",
+                                    test_ioctl_sparse_qar_overflow);
 
        suite->description = talloc_strdup(suite, "SMB2-IOCTL tests");