[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Tue May 29 10:56:04 MDT 2012
The branch, master has been updated
via cee146f s3:smb2_ioctl: verify credit charge
via 8b4e677 s3:smb2_ioctl: add more validation checks
via 4ac57a3 s3:smb2_ioctl: add some more validation checks
from c17f981 s4-torture: verify #8373 and add ndr nbt tests for LOGON_PRIMARY_QUERY nbt_netlogon_requests.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit cee146ff7c2250d3c723f19357fd1c8541191d08
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue May 29 14:08:43 2012 +0200
s3:smb2_ioctl: verify credit charge
Based on a patch from Christian Ambach <ambi at samba.org>.
metze
Autobuild-User: Stefan Metzmacher <metze at samba.org>
Autobuild-Date: Tue May 29 18:55:29 CEST 2012 on sn-devel-104
commit 8b4e6777206d7df4174f9d61830d1c337a46089f
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue May 29 13:25:31 2012 +0200
s3:smb2_ioctl: add more validation checks
metze
commit 4ac57a3c965603684c55dbc6b02d882331d85ede
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue May 29 12:06:22 2012 +0200
s3:smb2_ioctl: add some more validation checks
Based on a patch from Christian Ambach <ambi at samba.org>.
metze
-----------------------------------------------------------------------
Summary of changes:
source3/smbd/smb2_ioctl.c | 141 ++++++++++++++++++++++++++++++++++++++++----
1 files changed, 128 insertions(+), 13 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c
index cd303ed..0d17407 100644
--- a/source3/smbd/smb2_ioctl.c
+++ b/source3/smbd/smb2_ioctl.c
@@ -46,14 +46,27 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req)
NTSTATUS status;
const uint8_t *inbody;
int i = req->current_idx;
+ uint32_t min_buffer_offset;
+ uint32_t max_buffer_offset;
+ uint32_t min_output_offset;
+ uint32_t allowed_length_in;
+ uint32_t allowed_length_out;
uint32_t in_ctl_code;
uint64_t in_file_id_persistent;
uint64_t in_file_id_volatile;
uint32_t in_input_offset;
uint32_t in_input_length;
- DATA_BLOB in_input_buffer;
+ DATA_BLOB in_input_buffer = data_blob_null;
+ uint32_t in_max_input_length;
+ uint32_t in_output_offset;
+ uint32_t in_output_length;
+ 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);
@@ -67,9 +80,16 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req)
in_file_id_volatile = BVAL(inbody, 0x10);
in_input_offset = IVAL(inbody, 0x18);
in_input_length = IVAL(inbody, 0x1C);
+ in_max_input_length = IVAL(inbody, 0x20);
+ in_output_offset = IVAL(inbody, 0x24);
+ in_output_length = IVAL(inbody, 0x28);
in_max_output_length = IVAL(inbody, 0x2C);
in_flags = IVAL(inbody, 0x30);
+ min_buffer_offset = SMB2_HDR_BODY + req->in.vector[i+1].iov_len;
+ max_buffer_offset = min_buffer_offset + req->in.vector[i+2].iov_len;
+ min_output_offset = min_buffer_offset;
+
/*
* InputOffset (4 bytes): The offset, in bytes, from the beginning of
* the SMB2 header to the input data buffer. If no input data is
@@ -78,25 +98,120 @@ NTSTATUS smbd_smb2_request_process_ioctl(struct smbd_smb2_request *req)
* <49> If no input data is required for the FSCTL/IOCTL command being
* issued, Windows-based clients set this field to any value.
*/
- if ((in_input_length > 0)
- && (in_input_offset != (SMB2_HDR_BODY + req->in.vector[i+1].iov_len))) {
+ allowed_length_in = 0;
+ if ((in_input_offset > 0) && (in_input_length > 0)) {
+ uint32_t tmp_ofs;
+
+ if (in_input_offset < min_buffer_offset) {
+ return smbd_smb2_request_error(req,
+ NT_STATUS_INVALID_PARAMETER);
+ }
+ if (in_input_offset > max_buffer_offset) {
+ return smbd_smb2_request_error(req,
+ NT_STATUS_INVALID_PARAMETER);
+ }
+ allowed_length_in = max_buffer_offset - in_input_offset;
+
+ tmp_ofs = in_input_offset - min_buffer_offset;
+ in_input_buffer.data = (uint8_t *)req->in.vector[i+2].iov_base;
+ in_input_buffer.data += tmp_ofs;
+ in_input_buffer.length = in_input_length;
+ min_output_offset += tmp_ofs;
+ min_output_offset += in_input_length;
+ }
+
+ if (in_input_length > allowed_length_in) {
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
- if (in_input_length > req->in.vector[i+2].iov_len) {
+ allowed_length_out = 0;
+ if (in_output_offset > 0) {
+ if (in_output_offset < min_buffer_offset) {
+ return smbd_smb2_request_error(req,
+ NT_STATUS_INVALID_PARAMETER);
+ }
+ if (in_output_offset > max_buffer_offset) {
+ return smbd_smb2_request_error(req,
+ NT_STATUS_INVALID_PARAMETER);
+ }
+ allowed_length_out = max_buffer_offset - in_output_offset;
+ }
+
+ if (in_output_length > allowed_length_out) {
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
- in_input_buffer.data = (uint8_t *)req->in.vector[i+2].iov_base;
- in_input_buffer.length = in_input_length;
+ if (in_output_length > 0) {
+ uint32_t tmp_ofs;
- if (req->compat_chain_fsp) {
- /* skip check */
- } else if (in_file_id_persistent == UINT64_MAX &&
- in_file_id_volatile == UINT64_MAX) {
- /* without a handle */
- } else if (in_file_id_persistent != in_file_id_volatile) {
- return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
+ if (in_output_offset < min_output_offset) {
+ return smbd_smb2_request_error(req,
+ NT_STATUS_INVALID_PARAMETER);
+ }
+
+ tmp_ofs = in_output_offset - min_buffer_offset;
+ in_output_buffer.data = (uint8_t *)req->in.vector[i+2].iov_base;
+ in_output_buffer.data += tmp_ofs;
+ 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.
+ */
+ if (in_flags != SMB2_IOCTL_FLAG_IS_FSCTL) {
+ return smbd_smb2_request_error(req, NT_STATUS_NOT_SUPPORTED);
+ }
+
+ switch (in_ctl_code) {
+ case FSCTL_DFS_GET_REFERRALS:
+ case FSCTL_DFS_GET_REFERRALS_EX:
+ case FSCTL_PIPE_WAIT:
+ case FSCTL_VALIDATE_NEGOTIATE_INFO_224:
+ case FSCTL_VALIDATE_NEGOTIATE_INFO:
+ case FSCTL_QUERY_NETWORK_INTERFACE_INFO:
+ /*
+ * Some SMB2 specific CtlCodes like FSCTL_DFS_GET_REFERRALS or
+ * FSCTL_PIPE_WAIT does not take a file handle.
+ *
+ * If FileId in the SMB2 Header of the request is not
+ * 0xFFFFFFFFFFFFFFFF, then the server MUST fail the request
+ * with STATUS_INVALID_PARAMETER.
+ */
+ if (in_file_id_persistent != UINT64_MAX ||
+ in_file_id_volatile != UINT64_MAX) {
+ return smbd_smb2_request_error(req,
+ NT_STATUS_INVALID_PARAMETER);
+ }
+ break;
+ default:
+ if (req->compat_chain_fsp) {
+ /* skip check */
+ } else if (in_file_id_persistent != in_file_id_volatile) {
+ return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED);
+ }
+ break;
}
subreq = smbd_smb2_ioctl_send(req,
--
Samba Shared Repository
More information about the samba-cvs
mailing list