s3:smb2_ioctl: verify credit charge
authorStefan Metzmacher <metze@samba.org>
Tue, 29 May 2012 12:08:43 +0000 (14:08 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 29 May 2012 16:55:29 +0000 (18:55 +0200)
Based on a patch from Christian Ambach <ambi@samba.org>.

metze

Autobuild-User: Stefan Metzmacher <metze@samba.org>
Autobuild-Date: Tue May 29 18:55:29 CEST 2012 on sn-devel-104

source3/smbd/smb2_ioctl.c

index c83162e368004ae27fe43417d10031ad1307d2bc..0d17407cf3833e6da06b979c3b9e3a46827cdb6b 100644 (file)
@@ -63,6 +63,10 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req)
        DATA_BLOB in_output_buffer = data_blob_null;
        uint32_t in_max_output_length;
        uint32_t in_flags;
+       uint32_t data_length_in;
+       uint32_t data_length_out;
+       uint32_t data_length_tmp;
+       uint32_t data_length_max;
        struct tevent_req *subreq;
 
        status = smbd_smb2_request_verify_sizes(req, 0x39);
@@ -151,6 +155,27 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req)
                in_output_buffer.length = in_output_length;
        }
 
+       /*
+        * verify the credits and avoid overflows
+        * in_input_buffer.length and in_output_buffer.length
+        * are already verified.
+        */
+       data_length_in = in_input_buffer.length + in_output_buffer.length;
+
+       data_length_out = in_max_input_length;
+       data_length_tmp = UINT32_MAX - data_length_out;
+       if (data_length_tmp < in_max_output_length) {
+               return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+       }
+       data_length_out += in_max_output_length;
+
+       data_length_max = MAX(data_length_in, data_length_out);
+
+       status = smbd_smb2_request_verify_creditcharge(req, data_length_max);
+       if (!NT_STATUS_IS_OK(status)) {
+               return smbd_smb2_request_error(req, status);
+       }
+
        /*
         * If the Flags field of the request is not SMB2_0_IOCTL_IS_FSCTL the
         * server MUST fail the request with STATUS_NOT_SUPPORTED.