mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
s3/rpc_client: Fix array offset check
Previous to this commit we were modifying the offset before the array offset check. This was causing a spurious debug message indicating the offset was out of bounds. An second problem is that upon detecting the error we don't exit the loop. A third problem was that when reading the offset the check didn't cater for the size of the integer address about to be read. This commit moves the offset check to before the first read, additionally when an error is detected now we actually exit the loop and the offset have been corrected to include the size of the integer to be read BUG: https://bugzilla.samba.org/show_bug.cgi?id=15579 Signed-off-by: Noel Power <noel.power@suse.com> Reviewed-by: Volker Lendecke <vl@samba.org> Autobuild-User(master): Volker Lendecke <vl@samba.org> Autobuild-Date(master): Sat Feb 17 17:58:43 UTC 2024 on atb-devel-224
This commit is contained in:
parent
f487211706
commit
885850b6aa
@ -938,6 +938,15 @@ static enum ndr_err_code extract_variant_addresses(TALLOC_CTX *ctx,
|
|||||||
count = 1;
|
count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ensure count is at least within buffer range */
|
||||||
|
if (count >= MAX_ROW_BUFF_SIZE || count >= rows_buf->length) {
|
||||||
|
DBG_ERR("count %"PRIu64" either exceeds max buffer size "
|
||||||
|
"or buffer size (%zu)",
|
||||||
|
count, rows_buf->length);
|
||||||
|
err = NDR_ERR_VALIDATE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* read address */
|
/* read address */
|
||||||
if (is_64bit) {
|
if (is_64bit) {
|
||||||
err = ndr_pull_udlong(ndr_pull,
|
err = ndr_pull_udlong(ndr_pull,
|
||||||
@ -974,30 +983,64 @@ static enum ndr_err_code extract_variant_addresses(TALLOC_CTX *ctx,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* non vector case addr points to value
|
||||||
|
* otherwise addr points to list of addresses
|
||||||
|
* for the values in vector
|
||||||
|
*/
|
||||||
if (is_vector == false) {
|
if (is_vector == false) {
|
||||||
vec_address[0] = addr;
|
vec_address[0] = addr;
|
||||||
} else {
|
} else {
|
||||||
uint64_t array_offset = addr - baseaddress;
|
uint64_t array_offset = addr - baseaddress;
|
||||||
uint64_t i;
|
uint64_t i;
|
||||||
|
uint32_t intsize;
|
||||||
|
|
||||||
|
if (is_64bit) {
|
||||||
|
intsize = 8;
|
||||||
|
} else {
|
||||||
|
intsize = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_offset >= MAX_ROW_BUFF_SIZE
|
||||||
|
|| array_offset >= rows_buf->length) {
|
||||||
|
DBG_ERR("offset %"PRIu64" either exceeds max buf size "
|
||||||
|
"or buffer size (%zu)",
|
||||||
|
array_offset, rows_buf->length);
|
||||||
|
err = NDR_ERR_VALIDATE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* addr points to a list of int32 or int64 addresses */
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
/*
|
||||||
|
* read the addresses of the vector elements
|
||||||
|
* note: we can safely convert the uint64_t
|
||||||
|
* values here to uint32_t values as
|
||||||
|
* we are sure they are within range
|
||||||
|
* due to previous checks above.
|
||||||
|
*/
|
||||||
|
if (smb_buffer_oob((uint32_t)rows_buf->length,
|
||||||
|
(uint32_t)array_offset,
|
||||||
|
intsize)) {
|
||||||
|
DBG_ERR("offset %"PRIu64" will be outside "
|
||||||
|
"buffer range (buf len - %zu) after "
|
||||||
|
"reading %s address\n",
|
||||||
|
array_offset,
|
||||||
|
rows_buf->length,
|
||||||
|
is_64bit ? "64 bit" : "32 bit");
|
||||||
|
err = NDR_ERR_VALIDATE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
if (is_64bit) {
|
if (is_64bit) {
|
||||||
vec_address[i] =
|
vec_address[i] =
|
||||||
PULL_LE_I64(rows_buf->data,
|
PULL_LE_I64(rows_buf->data,
|
||||||
array_offset);
|
array_offset);
|
||||||
array_offset = array_offset + 8;
|
|
||||||
} else {
|
} else {
|
||||||
vec_address[i] =
|
vec_address[i] =
|
||||||
(uint32_t)PULL_LE_I32(rows_buf->data,
|
(uint32_t)PULL_LE_I32(rows_buf->data,
|
||||||
array_offset);
|
array_offset);
|
||||||
array_offset = array_offset + 4;
|
|
||||||
}
|
|
||||||
if (array_offset >= rows_buf->length) {
|
|
||||||
DBG_ERR("offset %"PRIu64" outside buffer range "
|
|
||||||
"(buf len - %zu)\n",
|
|
||||||
array_offset,
|
|
||||||
rows_buf->length);
|
|
||||||
err = NDR_ERR_VALIDATE;
|
|
||||||
}
|
}
|
||||||
|
array_offset += intsize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = NDR_ERR_SUCCESS;
|
err = NDR_ERR_SUCCESS;
|
||||||
|
Loading…
Reference in New Issue
Block a user