diff options
-rw-r--r-- | source3/librpc/gen_ndr/cli_svcctl.c | 34 | ||||
-rw-r--r-- | source3/librpc/gen_ndr/cli_svcctl.h | 32 | ||||
-rw-r--r-- | source3/librpc/gen_ndr/ndr_svcctl.c | 182 | ||||
-rw-r--r-- | source3/librpc/gen_ndr/srv_svcctl.c | 6 | ||||
-rw-r--r-- | source3/librpc/gen_ndr/svcctl.h | 34 |
5 files changed, 179 insertions, 109 deletions
diff --git a/source3/librpc/gen_ndr/cli_svcctl.c b/source3/librpc/gen_ndr/cli_svcctl.c index f67b447c6a..9f11a40d7e 100644 --- a/source3/librpc/gen_ndr/cli_svcctl.c +++ b/source3/librpc/gen_ndr/cli_svcctl.c @@ -702,10 +702,10 @@ NTSTATUS rpccli_svcctl_EnumServicesStatusW(struct rpc_pipe_client *cli, struct policy_handle *handle /* [in] [ref] */, uint32_t type /* [in] */, uint32_t state /* [in] */, - uint32_t buf_size /* [in] */, - uint8_t *service /* [out] [size_is(buf_size)] */, - uint32_t *bytes_needed /* [out] [ref] */, - uint32_t *services_returned /* [out] [ref] */, + uint8_t *service /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,262144)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,262144)] */, + uint32_t *services_returned /* [out] [ref,range(0,262144)] */, uint32_t *resume_handle /* [in,out] [unique] */, WERROR *werror) { @@ -1976,9 +1976,9 @@ NTSTATUS rpccli_svcctl_QueryServiceConfig2W(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, uint32_t info_level /* [in] */, - uint8_t *buffer /* [out] */, - uint32_t buf_size /* [in] */, - uint32_t *bytes_needed /* [out] [ref] */, + uint8_t *buffer /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,8192)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,8192)] */, WERROR *werror) { struct svcctl_QueryServiceConfig2W r; @@ -2027,9 +2027,9 @@ NTSTATUS rpccli_svcctl_QueryServiceStatusEx(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, uint32_t info_level /* [in] */, - uint8_t *buffer /* [out] */, - uint32_t buf_size /* [in] */, - uint32_t *bytes_needed /* [out] [ref] */, + uint8_t *buffer /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,8192)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,8192)] */, WERROR *werror) { struct svcctl_QueryServiceStatusEx r; @@ -2144,12 +2144,12 @@ NTSTATUS rpccli_EnumServicesStatusExW(struct rpc_pipe_client *cli, uint32_t info_level /* [in] */, uint32_t type /* [in] */, uint32_t state /* [in] */, - uint8_t *services /* [out] */, - uint32_t buf_size /* [in] */, - uint32_t *bytes_needed /* [out] [ref] */, - uint32_t *service_returned /* [out] [ref] */, - uint32_t *resume_handle /* [in,out] [unique] */, - const char **group_name /* [out] [ref,charset(UTF16)] */, + uint8_t *services /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,262144)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,262144)] */, + uint32_t *service_returned /* [out] [ref,range(0,262144)] */, + uint32_t *resume_handle /* [in,out] [unique,range(0,262144)] */, + const char *group_name /* [in] [unique,charset(UTF16)] */, WERROR *werror) { struct EnumServicesStatusExW r; @@ -2162,6 +2162,7 @@ NTSTATUS rpccli_EnumServicesStatusExW(struct rpc_pipe_client *cli, r.in.state = state; r.in.buf_size = buf_size; r.in.resume_handle = resume_handle; + r.in.group_name = group_name; if (DEBUGLEVEL >= 10) { NDR_PRINT_IN_DEBUG(EnumServicesStatusExW, &r); @@ -2192,7 +2193,6 @@ NTSTATUS rpccli_EnumServicesStatusExW(struct rpc_pipe_client *cli, if (resume_handle && r.out.resume_handle) { *resume_handle = *r.out.resume_handle; } - *group_name = *r.out.group_name; /* Return result */ if (werror) { diff --git a/source3/librpc/gen_ndr/cli_svcctl.h b/source3/librpc/gen_ndr/cli_svcctl.h index 4e4e223243..78c9bf40d8 100644 --- a/source3/librpc/gen_ndr/cli_svcctl.h +++ b/source3/librpc/gen_ndr/cli_svcctl.h @@ -104,10 +104,10 @@ NTSTATUS rpccli_svcctl_EnumServicesStatusW(struct rpc_pipe_client *cli, struct policy_handle *handle /* [in] [ref] */, uint32_t type /* [in] */, uint32_t state /* [in] */, - uint32_t buf_size /* [in] */, - uint8_t *service /* [out] [size_is(buf_size)] */, - uint32_t *bytes_needed /* [out] [ref] */, - uint32_t *services_returned /* [out] [ref] */, + uint8_t *service /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,262144)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,262144)] */, + uint32_t *services_returned /* [out] [ref,range(0,262144)] */, uint32_t *resume_handle /* [in,out] [unique] */, WERROR *werror); NTSTATUS rpccli_svcctl_OpenSCManagerW(struct rpc_pipe_client *cli, @@ -292,17 +292,17 @@ NTSTATUS rpccli_svcctl_QueryServiceConfig2W(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, uint32_t info_level /* [in] */, - uint8_t *buffer /* [out] */, - uint32_t buf_size /* [in] */, - uint32_t *bytes_needed /* [out] [ref] */, + uint8_t *buffer /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,8192)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,8192)] */, WERROR *werror); NTSTATUS rpccli_svcctl_QueryServiceStatusEx(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *handle /* [in] [ref] */, uint32_t info_level /* [in] */, - uint8_t *buffer /* [out] */, - uint32_t buf_size /* [in] */, - uint32_t *bytes_needed /* [out] [ref] */, + uint8_t *buffer /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,8192)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,8192)] */, WERROR *werror); NTSTATUS rpccli_EnumServicesStatusExA(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, @@ -323,12 +323,12 @@ NTSTATUS rpccli_EnumServicesStatusExW(struct rpc_pipe_client *cli, uint32_t info_level /* [in] */, uint32_t type /* [in] */, uint32_t state /* [in] */, - uint8_t *services /* [out] */, - uint32_t buf_size /* [in] */, - uint32_t *bytes_needed /* [out] [ref] */, - uint32_t *service_returned /* [out] [ref] */, - uint32_t *resume_handle /* [in,out] [unique] */, - const char **group_name /* [out] [ref,charset(UTF16)] */, + uint8_t *services /* [out] [ref,size_is(buf_size)] */, + uint32_t buf_size /* [in] [range(0,262144)] */, + uint32_t *bytes_needed /* [out] [ref,range(0,262144)] */, + uint32_t *service_returned /* [out] [ref,range(0,262144)] */, + uint32_t *resume_handle /* [in,out] [unique,range(0,262144)] */, + const char *group_name /* [in] [unique,charset(UTF16)] */, WERROR *werror); NTSTATUS rpccli_svcctl_SCSendTSMessage(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/librpc/gen_ndr/ndr_svcctl.c b/source3/librpc/gen_ndr/ndr_svcctl.c index b417ba0a5c..2bccde9ba0 100644 --- a/source3/librpc/gen_ndr/ndr_svcctl.c +++ b/source3/librpc/gen_ndr/ndr_svcctl.c @@ -2123,6 +2123,9 @@ static enum ndr_err_code ndr_push_svcctl_EnumServicesStatusW(struct ndr_push *nd } } if (flags & NDR_OUT) { + if (r->out.service == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.service, r->in.buf_size)); if (r->out.bytes_needed == NULL) { @@ -2162,6 +2165,9 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.type)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.state)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size)); + if (r->in.buf_size < 0 || r->in.buf_size > 262144) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle)); if (_ptr_resume_handle) { NDR_PULL_ALLOC(ndr, r->in.resume_handle); @@ -2174,6 +2180,8 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.resume_handle)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0); } + NDR_PULL_ALLOC_N(ndr, r->out.service, r->in.buf_size); + memset(r->out.service, 0, (r->in.buf_size) * sizeof(*r->out.service)); NDR_PULL_ALLOC(ndr, r->out.bytes_needed); ZERO_STRUCTP(r->out.bytes_needed); NDR_PULL_ALLOC(ndr, r->out.services_returned); @@ -2181,7 +2189,9 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd } if (flags & NDR_OUT) { NDR_CHECK(ndr_pull_array_size(ndr, &r->out.service)); - NDR_PULL_ALLOC_N(ndr, r->out.service, ndr_get_array_size(ndr, &r->out.service)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC_N(ndr, r->out.service, ndr_get_array_size(ndr, &r->out.service)); + } NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.service, ndr_get_array_size(ndr, &r->out.service))); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.bytes_needed); @@ -2189,6 +2199,9 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd _mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed)); + if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 262144) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.services_returned); @@ -2196,6 +2209,9 @@ static enum ndr_err_code ndr_pull_svcctl_EnumServicesStatusW(struct ndr_pull *nd _mem_save_services_returned_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.services_returned, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.services_returned)); + if (*r->out.services_returned < 0 || *r->out.services_returned > 262144) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_services_returned_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle)); if (_ptr_resume_handle) { @@ -2245,7 +2261,10 @@ _PUBLIC_ void ndr_print_svcctl_EnumServicesStatusW(struct ndr_print *ndr, const if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "svcctl_EnumServicesStatusW"); ndr->depth++; + ndr_print_ptr(ndr, "service", r->out.service); + ndr->depth++; ndr_print_array_uint8(ndr, "service", r->out.service, r->in.buf_size); + ndr->depth--; ndr_print_ptr(ndr, "bytes_needed", r->out.bytes_needed); ndr->depth++; ndr_print_uint32(ndr, "bytes_needed", *r->out.bytes_needed); @@ -5333,6 +5352,10 @@ static enum ndr_err_code ndr_push_svcctl_QueryServiceConfig2W(struct ndr_push *n NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); } if (flags & NDR_OUT) { + if (r->out.buffer == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buf_size)); if (r->out.bytes_needed == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -5359,20 +5382,34 @@ static enum ndr_err_code ndr_pull_svcctl_QueryServiceConfig2W(struct ndr_pull *n NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.info_level)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size)); + if (r->in.buf_size < 0 || r->in.buf_size > 8192) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size); + memset(r->out.buffer, 0, (r->in.buf_size) * sizeof(*r->out.buffer)); NDR_PULL_ALLOC(ndr, r->out.bytes_needed); ZERO_STRUCTP(r->out.bytes_needed); } if (flags & NDR_OUT) { - NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size); - NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buf_size)); + NDR_CHECK(ndr_pull_array_size(ndr, &r->out.buffer)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC_N(ndr, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer)); + } + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer))); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.bytes_needed); } _mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed)); + if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 8192) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + if (r->out.buffer) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.buffer, r->in.buf_size)); + } } return NDR_ERR_SUCCESS; } @@ -5398,7 +5435,10 @@ _PUBLIC_ void ndr_print_svcctl_QueryServiceConfig2W(struct ndr_print *ndr, const if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "svcctl_QueryServiceConfig2W"); ndr->depth++; + ndr_print_ptr(ndr, "buffer", r->out.buffer); + ndr->depth++; ndr_print_array_uint8(ndr, "buffer", r->out.buffer, r->in.buf_size); + ndr->depth--; ndr_print_ptr(ndr, "bytes_needed", r->out.bytes_needed); ndr->depth++; ndr_print_uint32(ndr, "bytes_needed", *r->out.bytes_needed); @@ -5420,6 +5460,10 @@ static enum ndr_err_code ndr_push_svcctl_QueryServiceStatusEx(struct ndr_push *n NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); } if (flags & NDR_OUT) { + if (r->out.buffer == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buf_size)); if (r->out.bytes_needed == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -5446,20 +5490,34 @@ static enum ndr_err_code ndr_pull_svcctl_QueryServiceStatusEx(struct ndr_pull *n NDR_PULL_SET_MEM_CTX(ndr, _mem_save_handle_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.info_level)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size)); + if (r->in.buf_size < 0 || r->in.buf_size > 8192) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size); + memset(r->out.buffer, 0, (r->in.buf_size) * sizeof(*r->out.buffer)); NDR_PULL_ALLOC(ndr, r->out.bytes_needed); ZERO_STRUCTP(r->out.bytes_needed); } if (flags & NDR_OUT) { - NDR_PULL_ALLOC_N(ndr, r->out.buffer, r->in.buf_size); - NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, r->in.buf_size)); + NDR_CHECK(ndr_pull_array_size(ndr, &r->out.buffer)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC_N(ndr, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer)); + } + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.buffer, ndr_get_array_size(ndr, &r->out.buffer))); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.bytes_needed); } _mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed)); + if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 8192) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + if (r->out.buffer) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.buffer, r->in.buf_size)); + } } return NDR_ERR_SUCCESS; } @@ -5485,7 +5543,10 @@ _PUBLIC_ void ndr_print_svcctl_QueryServiceStatusEx(struct ndr_print *ndr, const if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "svcctl_QueryServiceStatusEx"); ndr->depth++; + ndr_print_ptr(ndr, "buffer", r->out.buffer); + ndr->depth++; ndr_print_array_uint8(ndr, "buffer", r->out.buffer, r->in.buf_size); + ndr->depth--; ndr_print_ptr(ndr, "bytes_needed", r->out.bytes_needed); ndr->depth++; ndr_print_uint32(ndr, "bytes_needed", *r->out.bytes_needed); @@ -5716,8 +5777,19 @@ static enum ndr_err_code ndr_push_EnumServicesStatusExW(struct ndr_push *ndr, in if (r->in.resume_handle) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->in.resume_handle)); } + NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.group_name)); + if (r->in.group_name) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.group_name, CH_UTF16))); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.group_name, CH_UTF16))); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.group_name, ndr_charset_length(r->in.group_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); + } } if (flags & NDR_OUT) { + if (r->out.services == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.buf_size)); NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->out.services, r->in.buf_size)); if (r->out.bytes_needed == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); @@ -5731,16 +5803,6 @@ static enum ndr_err_code ndr_push_EnumServicesStatusExW(struct ndr_push *ndr, in if (r->out.resume_handle) { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, *r->out.resume_handle)); } - if (r->out.group_name == NULL) { - return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); - } - NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.group_name)); - if (*r->out.group_name) { - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(*r->out.group_name, CH_UTF16))); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(*r->out.group_name, CH_UTF16))); - NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, *r->out.group_name, ndr_charset_length(*r->out.group_name, CH_UTF16), sizeof(uint16_t), CH_UTF16)); - } NDR_CHECK(ndr_push_WERROR(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -5755,7 +5817,6 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in TALLOC_CTX *_mem_save_service_returned_0; TALLOC_CTX *_mem_save_resume_handle_0; TALLOC_CTX *_mem_save_group_name_0; - TALLOC_CTX *_mem_save_group_name_1; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -5770,6 +5831,9 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.type)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.state)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.buf_size)); + if (r->in.buf_size < 0 || r->in.buf_size > 262144) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle)); if (_ptr_resume_handle) { NDR_PULL_ALLOC(ndr, r->in.resume_handle); @@ -5780,24 +5844,51 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in _mem_save_resume_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->in.resume_handle, 0); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->in.resume_handle)); + if (*r->in.resume_handle < 0 || *r->in.resume_handle > 262144) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0); } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_group_name)); + if (_ptr_group_name) { + NDR_PULL_ALLOC(ndr, r->in.group_name); + } else { + r->in.group_name = NULL; + } + if (r->in.group_name) { + _mem_save_group_name_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.group_name, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->in.group_name)); + NDR_CHECK(ndr_pull_array_length(ndr, &r->in.group_name)); + if (ndr_get_array_length(ndr, &r->in.group_name) > ndr_get_array_size(ndr, &r->in.group_name)) { + return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, &r->in.group_name), ndr_get_array_length(ndr, &r->in.group_name)); + } + NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.group_name), sizeof(uint16_t))); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.group_name, ndr_get_array_length(ndr, &r->in.group_name), sizeof(uint16_t), CH_UTF16)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_group_name_0, 0); + } + NDR_PULL_ALLOC_N(ndr, r->out.services, r->in.buf_size); + memset(r->out.services, 0, (r->in.buf_size) * sizeof(*r->out.services)); NDR_PULL_ALLOC(ndr, r->out.bytes_needed); ZERO_STRUCTP(r->out.bytes_needed); NDR_PULL_ALLOC(ndr, r->out.service_returned); ZERO_STRUCTP(r->out.service_returned); - NDR_PULL_ALLOC(ndr, r->out.group_name); - ZERO_STRUCTP(r->out.group_name); } if (flags & NDR_OUT) { - NDR_PULL_ALLOC_N(ndr, r->out.services, r->in.buf_size); - NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.services, r->in.buf_size)); + NDR_CHECK(ndr_pull_array_size(ndr, &r->out.services)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC_N(ndr, r->out.services, ndr_get_array_size(ndr, &r->out.services)); + } + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->out.services, ndr_get_array_size(ndr, &r->out.services))); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.bytes_needed); } _mem_save_bytes_needed_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.bytes_needed, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.bytes_needed)); + if (*r->out.bytes_needed < 0 || *r->out.bytes_needed > 262144) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_bytes_needed_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->out.service_returned); @@ -5805,6 +5896,9 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in _mem_save_service_returned_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.service_returned, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.service_returned)); + if (*r->out.service_returned < 0 || *r->out.service_returned > 262144) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_service_returned_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_resume_handle)); if (_ptr_resume_handle) { @@ -5816,33 +5910,15 @@ static enum ndr_err_code ndr_pull_EnumServicesStatusExW(struct ndr_pull *ndr, in _mem_save_resume_handle_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.resume_handle, 0); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, r->out.resume_handle)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0); - } - if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { - NDR_PULL_ALLOC(ndr, r->out.group_name); - } - _mem_save_group_name_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->out.group_name, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_group_name)); - if (_ptr_group_name) { - NDR_PULL_ALLOC(ndr, *r->out.group_name); - } else { - *r->out.group_name = NULL; - } - if (*r->out.group_name) { - _mem_save_group_name_1 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, *r->out.group_name, 0); - NDR_CHECK(ndr_pull_array_size(ndr, r->out.group_name)); - NDR_CHECK(ndr_pull_array_length(ndr, r->out.group_name)); - if (ndr_get_array_length(ndr, r->out.group_name) > ndr_get_array_size(ndr, r->out.group_name)) { - return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "Bad array size %u should exceed array length %u", ndr_get_array_size(ndr, r->out.group_name), ndr_get_array_length(ndr, r->out.group_name)); + if (*r->out.resume_handle < 0 || *r->out.resume_handle > 262144) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } - NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, r->out.group_name), sizeof(uint16_t))); - NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, r->out.group_name, ndr_get_array_length(ndr, r->out.group_name), sizeof(uint16_t), CH_UTF16)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_group_name_1, 0); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_resume_handle_0, 0); } - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_group_name_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_WERROR(ndr, NDR_SCALARS, &r->out.result)); + if (r->out.services) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->out.services, r->in.buf_size)); + } } return NDR_ERR_SUCCESS; } @@ -5871,12 +5947,21 @@ _PUBLIC_ void ndr_print_EnumServicesStatusExW(struct ndr_print *ndr, const char ndr_print_uint32(ndr, "resume_handle", *r->in.resume_handle); } ndr->depth--; + ndr_print_ptr(ndr, "group_name", r->in.group_name); + ndr->depth++; + if (r->in.group_name) { + ndr_print_string(ndr, "group_name", r->in.group_name); + } + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { ndr_print_struct(ndr, "out", "EnumServicesStatusExW"); ndr->depth++; + ndr_print_ptr(ndr, "services", r->out.services); + ndr->depth++; ndr_print_array_uint8(ndr, "services", r->out.services, r->in.buf_size); + ndr->depth--; ndr_print_ptr(ndr, "bytes_needed", r->out.bytes_needed); ndr->depth++; ndr_print_uint32(ndr, "bytes_needed", *r->out.bytes_needed); @@ -5891,15 +5976,6 @@ _PUBLIC_ void ndr_print_EnumServicesStatusExW(struct ndr_print *ndr, const char ndr_print_uint32(ndr, "resume_handle", *r->out.resume_handle); } ndr->depth--; - ndr_print_ptr(ndr, "group_name", r->out.group_name); - ndr->depth++; - ndr_print_ptr(ndr, "group_name", *r->out.group_name); - ndr->depth++; - if (*r->out.group_name) { - ndr_print_string(ndr, "group_name", *r->out.group_name); - } - ndr->depth--; - ndr->depth--; ndr_print_WERROR(ndr, "result", r->out.result); ndr->depth--; } diff --git a/source3/librpc/gen_ndr/srv_svcctl.c b/source3/librpc/gen_ndr/srv_svcctl.c index 2349b4fd93..f37111137e 100644 --- a/source3/librpc/gen_ndr/srv_svcctl.c +++ b/source3/librpc/gen_ndr/srv_svcctl.c @@ -3445,12 +3445,6 @@ static bool api_EnumServicesStatusExW(pipes_struct *p) } r->out.resume_handle = r->in.resume_handle; - r->out.group_name = talloc_zero(r, const char *); - if (r->out.group_name == NULL) { - talloc_free(r); - return false; - } - r->out.result = _EnumServicesStatusExW(p, r); if (p->rng_fault_state) { diff --git a/source3/librpc/gen_ndr/svcctl.h b/source3/librpc/gen_ndr/svcctl.h index 631cc2af7a..9baa122e56 100644 --- a/source3/librpc/gen_ndr/svcctl.h +++ b/source3/librpc/gen_ndr/svcctl.h @@ -341,14 +341,14 @@ struct svcctl_EnumServicesStatusW { struct policy_handle *handle;/* [ref] */ uint32_t type; uint32_t state; - uint32_t buf_size; + uint32_t buf_size;/* [range(0,262144)] */ uint32_t *resume_handle;/* [unique] */ } in; struct { - uint8_t *service;/* [size_is(buf_size)] */ - uint32_t *bytes_needed;/* [ref] */ - uint32_t *services_returned;/* [ref] */ + uint8_t *service;/* [ref,size_is(buf_size)] */ + uint32_t *bytes_needed;/* [ref,range(0,262144)] */ + uint32_t *services_returned;/* [ref,range(0,262144)] */ uint32_t *resume_handle;/* [unique] */ WERROR result; } out; @@ -729,12 +729,12 @@ struct svcctl_QueryServiceConfig2W { struct { struct policy_handle *handle;/* [ref] */ uint32_t info_level; - uint32_t buf_size; + uint32_t buf_size;/* [range(0,8192)] */ } in; struct { - uint8_t *buffer; - uint32_t *bytes_needed;/* [ref] */ + uint8_t *buffer;/* [ref,size_is(buf_size)] */ + uint32_t *bytes_needed;/* [ref,range(0,8192)] */ WERROR result; } out; @@ -745,12 +745,12 @@ struct svcctl_QueryServiceStatusEx { struct { struct policy_handle *handle;/* [ref] */ uint32_t info_level; - uint32_t buf_size; + uint32_t buf_size;/* [range(0,8192)] */ } in; struct { - uint8_t *buffer; - uint32_t *bytes_needed;/* [ref] */ + uint8_t *buffer;/* [ref,size_is(buf_size)] */ + uint32_t *bytes_needed;/* [ref,range(0,8192)] */ WERROR result; } out; @@ -785,16 +785,16 @@ struct EnumServicesStatusExW { uint32_t info_level; uint32_t type; uint32_t state; - uint32_t buf_size; - uint32_t *resume_handle;/* [unique] */ + uint32_t buf_size;/* [range(0,262144)] */ + const char *group_name;/* [unique,charset(UTF16)] */ + uint32_t *resume_handle;/* [unique,range(0,262144)] */ } in; struct { - uint8_t *services; - uint32_t *bytes_needed;/* [ref] */ - uint32_t *service_returned;/* [ref] */ - const char **group_name;/* [ref,charset(UTF16)] */ - uint32_t *resume_handle;/* [unique] */ + uint8_t *services;/* [ref,size_is(buf_size)] */ + uint32_t *bytes_needed;/* [ref,range(0,262144)] */ + uint32_t *service_returned;/* [ref,range(0,262144)] */ + uint32_t *resume_handle;/* [unique,range(0,262144)] */ WERROR result; } out; |