1
0
mirror of https://github.com/samba-team/samba.git synced 2025-08-26 01:49:31 +03:00

librpc: Fix string length checking in ndr_pull_charset_to_null()

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14219

Pair-Programmed-With: Guenther Deschner <gd@samba.org>
Signed-off-by: Guenther Deschner <gd@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
(cherry picked from commit f11e207e01)
This commit is contained in:
Andreas Schneider
2019-12-16 15:50:17 +01:00
committed by Karolin Seeger
parent fe015ece4e
commit 6a109e3ddb

View File

@ -553,6 +553,47 @@ _PUBLIC_ uint32_t ndr_string_length(const void *_var, uint32_t element_size)
return i+1;
}
/**
* @brief Get the string length including the null terminator if available.
*
* This checks the string length based on the elements. The returned number
* includes the terminating null byte(s) if found.
*
* @param[in] _var The string the calculate the length for.
*
* @param[in] length The length of the buffer passed by _var.
*
* @param[in] element_size The element_size of a string char in bytes.
*
* @return The length of the strings or 0.
*/
static uint32_t ndr_string_n_length(const void *_var,
size_t length,
uint32_t element_size)
{
size_t i = 0;
uint8_t zero[4] = {0,0,0,0};
const char *var = (const char *)_var;
int cmp;
if (element_size > 4) {
return 0;
}
for (i = 0; i < length; i++, var += element_size) {
cmp = memcmp(var, zero, element_size);
if (cmp == 0) {
break;
}
}
if (i == length) {
return length;
}
return i + 1;
}
_PUBLIC_ enum ndr_err_code ndr_check_string_terminator(struct ndr_pull *ndr, uint32_t count, uint32_t element_size)
{
uint32_t i;
@ -622,8 +663,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_charset_to_null(struct ndr_pull *ndr, int nd
NDR_PULL_NEED_BYTES(ndr, length*byte_mul);
str_len = ndr_string_length(ndr->data+ndr->offset, byte_mul);
str_len = MIN(str_len, length); /* overrun protection */
str_len = ndr_string_n_length(ndr->data+ndr->offset, length, byte_mul);
if (str_len == 0) {
return ndr_pull_error(ndr, NDR_ERR_LENGTH,
"Invalid length");
}
if (!convert_string_talloc(ndr->current_mem_ctx, chset, CH_UNIX,
ndr->data+ndr->offset, str_len*byte_mul,
discard_const_p(void *, var),