From 346844b730b06fe5ad53dc93fc0f4d4470794cb5 Mon Sep 17 00:00:00 2001 From: Joseph Sutton Date: Thu, 21 Dec 2023 11:51:19 +1300 Subject: [PATCH] =?UTF-8?q?librpc:=20Change=20type=20of=20=E2=80=98u16stri?= =?UTF-8?q?ng=E2=80=99=20from=20=E2=80=98const=20uint16=5Ft=20*=E2=80=99?= =?UTF-8?q?=20to=20=E2=80=98const=20unsigned=20char=20*=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A u16string is supposed to contain UTF‐16 code units, but ndr_pull_u16string() and ndr_push_u16string() fail to correctly ensure this on big‐endian systems. Code that relies on the u16string array containing correct values will then fail. Fix ndr_pull_u16string() and ndr_push_u16string() to work on big‐endian systems, ensuring that other code can use these strings without having to worry about first encoding them to little‐endian. Signed-off-by: Joseph Sutton Reviewed-by: Andrew Bartlett --- lib/util/charset/charset.h | 6 ++-- lib/util/charset/util_unistr.c | 25 ++++++--------- librpc/ABI/ndr-4.0.0.sigs | 6 ++-- librpc/ndr/libndr.h | 2 +- librpc/ndr/ndr_string.c | 14 ++++----- librpc/tests/test_ndr_gmsa.c | 47 ++++++++++++++++------------ pidl/lib/Parse/Pidl/Samba4/Python.pm | 2 +- pidl/lib/Parse/Pidl/Typelist.pm | 2 +- source4/librpc/rpc/pyrpc_util.c | 6 ++-- source4/librpc/rpc/pyrpc_util.h | 4 +-- 10 files changed, 58 insertions(+), 56 deletions(-) diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h index aa691734713..12dc348bdb7 100644 --- a/lib/util/charset/charset.h +++ b/lib/util/charset/charset.h @@ -129,9 +129,9 @@ limited by 'n' bytes **/ size_t utf16_null_terminated_len_n(const void *src, size_t n); -uint16_t *talloc_utf16_strlendup(TALLOC_CTX *mem_ctx, const char *str, size_t len); -uint16_t *talloc_utf16_strdup(TALLOC_CTX *mem_ctx, const char *str); -uint16_t *talloc_utf16_strndup(TALLOC_CTX *mem_ctx, const char *str, size_t n); +unsigned char *talloc_utf16_strlendup(TALLOC_CTX *mem_ctx, const char *str, size_t len); +unsigned char *talloc_utf16_strdup(TALLOC_CTX *mem_ctx, const char *str); +unsigned char *talloc_utf16_strndup(TALLOC_CTX *mem_ctx, const char *str, size_t n); char *strchr_m(const char *s, char c); /** diff --git a/lib/util/charset/util_unistr.c b/lib/util/charset/util_unistr.c index fa1a100e596..830b4808c54 100644 --- a/lib/util/charset/util_unistr.c +++ b/lib/util/charset/util_unistr.c @@ -243,9 +243,9 @@ size_t utf16_null_terminated_len_n(const void *src, size_t n) return len; } -uint16_t *talloc_utf16_strlendup(TALLOC_CTX *mem_ctx, const char *str, size_t len) +unsigned char *talloc_utf16_strlendup(TALLOC_CTX *mem_ctx, const char *str, size_t len) { - uint16_t *new_str = NULL; + unsigned char *new_str = NULL; /* Check for overflow. */ if (len > SIZE_MAX - 2) { @@ -263,22 +263,17 @@ uint16_t *talloc_utf16_strlendup(TALLOC_CTX *mem_ctx, const char *str, size_t le memcpy(new_str, str, len); - { - /* - * Ensure that the UTF‐16 string is - * null‐terminated. - */ - - char *new_bytes = (char *)new_str; - - new_bytes[len] = '\0'; - new_bytes[len + 1] = '\0'; - } + /* + * Ensure that the UTF‐16 string is + * null‐terminated. + */ + new_str[len] = '\0'; + new_str[len + 1] = '\0'; return new_str; } -uint16_t *talloc_utf16_strdup(TALLOC_CTX *mem_ctx, const char *str) +unsigned char *talloc_utf16_strdup(TALLOC_CTX *mem_ctx, const char *str) { if (str == NULL) { return NULL; @@ -286,7 +281,7 @@ uint16_t *talloc_utf16_strdup(TALLOC_CTX *mem_ctx, const char *str) return talloc_utf16_strlendup(mem_ctx, str, utf16_len(str)); } -uint16_t *talloc_utf16_strndup(TALLOC_CTX *mem_ctx, const char *str, size_t n) +unsigned char *talloc_utf16_strndup(TALLOC_CTX *mem_ctx, const char *str, size_t n) { if (str == NULL) { return NULL; diff --git a/librpc/ABI/ndr-4.0.0.sigs b/librpc/ABI/ndr-4.0.0.sigs index 66a1b64cf60..5474a5184b0 100644 --- a/librpc/ABI/ndr-4.0.0.sigs +++ b/librpc/ABI/ndr-4.0.0.sigs @@ -81,7 +81,7 @@ ndr_print_svcctl_ServerType: void (struct ndr_print *, const char *, uint32_t) ndr_print_time_t: void (struct ndr_print *, const char *, time_t) ndr_print_timespec: void (struct ndr_print *, const char *, const struct timespec *) ndr_print_timeval: void (struct ndr_print *, const char *, const struct timeval *) -ndr_print_u16string: void (struct ndr_print *, const char *, const uint16_t *) +ndr_print_u16string: void (struct ndr_print *, const char *, const unsigned char *) ndr_print_udlong: void (struct ndr_print *, const char *, uint64_t) ndr_print_udlongr: void (struct ndr_print *, const char *, uint64_t) ndr_print_uid_t: void (struct ndr_print *, const char *, uid_t) @@ -158,7 +158,7 @@ ndr_pull_time_t: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, time_t *) ndr_pull_timespec: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, struct timespec *) ndr_pull_timeval: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, struct timeval *) ndr_pull_trailer_align: enum ndr_err_code (struct ndr_pull *, size_t) -ndr_pull_u16string: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, const uint16_t **) +ndr_pull_u16string: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, const unsigned char **) ndr_pull_udlong: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, uint64_t *) ndr_pull_udlongr: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, uint64_t *) ndr_pull_uid_t: enum ndr_err_code (struct ndr_pull *, ndr_flags_type, uid_t *) @@ -234,7 +234,7 @@ ndr_push_time_t: enum ndr_err_code (struct ndr_push *, ndr_flags_type, time_t) ndr_push_timespec: enum ndr_err_code (struct ndr_push *, ndr_flags_type, const struct timespec *) ndr_push_timeval: enum ndr_err_code (struct ndr_push *, ndr_flags_type, const struct timeval *) ndr_push_trailer_align: enum ndr_err_code (struct ndr_push *, size_t) -ndr_push_u16string: enum ndr_err_code (struct ndr_push *, ndr_flags_type, const uint16_t *) +ndr_push_u16string: enum ndr_err_code (struct ndr_push *, ndr_flags_type, const unsigned char *) ndr_push_udlong: enum ndr_err_code (struct ndr_push *, ndr_flags_type, uint64_t) ndr_push_udlongr: enum ndr_err_code (struct ndr_push *, ndr_flags_type, uint64_t) ndr_push_uid_t: enum ndr_err_code (struct ndr_push *, ndr_flags_type, uid_t) diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h index adcbdf18c0c..70dd01e49a6 100644 --- a/librpc/ndr/libndr.h +++ b/librpc/ndr/libndr.h @@ -806,7 +806,7 @@ NDR_SCALAR_PROTO(DATA_BLOB, DATA_BLOB) NDR_SCALAR_PROTO(ipv4address, const char *) NDR_SCALAR_PROTO(ipv6address, const char *) NDR_SCALAR_PROTO(string, const char *) -NDR_SCALAR_PROTO(u16string, const uint16_t *) +NDR_SCALAR_PROTO(u16string, const unsigned char *) NDR_SCALAR_PROTO(double, double) enum ndr_err_code ndr_pull_policy_handle(struct ndr_pull *ndr, ndr_flags_type ndr_flags, struct policy_handle *r); diff --git a/librpc/ndr/ndr_string.c b/librpc/ndr/ndr_string.c index 2ad139b420b..89ba8b0579b 100644 --- a/librpc/ndr/ndr_string.c +++ b/librpc/ndr/ndr_string.c @@ -481,9 +481,9 @@ _PUBLIC_ uint32_t ndr_size_string(int ret, const char * const* string, ndr_flags */ _PUBLIC_ enum ndr_err_code ndr_pull_u16string(struct ndr_pull *ndr, ndr_flags_type ndr_flags, - const uint16_t **s) + const unsigned char **s) { - uint16_t *as = NULL; + unsigned char *as = NULL; const char *const src_str = (char *)ndr->data + ndr->offset; size_t src_len = 0; @@ -544,7 +544,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_u16string(struct ndr_pull *ndr, */ _PUBLIC_ enum ndr_err_code ndr_push_u16string(struct ndr_push *ndr, ndr_flags_type ndr_flags, - const uint16_t *s) + const unsigned char *s) { size_t s_len; @@ -578,12 +578,12 @@ _PUBLIC_ enum ndr_err_code ndr_push_u16string(struct ndr_push *ndr, switch (ndr->flags & LIBNDR_STRING_FLAGS) { case LIBNDR_FLAG_STR_NULLTERM: - NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)s, s_len)); + NDR_CHECK(ndr_push_bytes(ndr, s, s_len)); break; default: if (ndr->flags & LIBNDR_FLAG_REMAINING) { - NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)s, s_len)); + NDR_CHECK(ndr_push_bytes(ndr, s, s_len)); break; } @@ -600,11 +600,11 @@ _PUBLIC_ enum ndr_err_code ndr_push_u16string(struct ndr_push *ndr, _PUBLIC_ void ndr_print_u16string(struct ndr_print *ndr, const char *name, - const uint16_t *s) + const unsigned char *s) { return ndr_print_array_uint8(ndr, name, - (const uint8_t *)s, + s, utf16_len(s)); } diff --git a/librpc/tests/test_ndr_gmsa.c b/librpc/tests/test_ndr_gmsa.c index 9834ce7249a..67aa7c2ba2e 100644 --- a/librpc/tests/test_ndr_gmsa.c +++ b/librpc/tests/test_ndr_gmsa.c @@ -27,21 +27,24 @@ #include "lib/replace/replace.h" #include "lib/util/attr.h" +#include "lib/util/bytearray.h" #include "librpc/gen_ndr/ndr_gmsa.h" #include "librpc/gen_ndr/gmsa.h" -static void assert_utf16_equal(const uint16_t *s1, const uint16_t *s2) +static void assert_utf16_equal(const unsigned char *s1, const unsigned char *s2) { uint16_t c1; uint16_t c2; + size_t n = 0; assert_non_null(s1); assert_non_null(s2); do { - c1 = *s1++; - c2 = *s2++; + c1 = PULL_LE_U16(s1, n); + c2 = PULL_LE_U16(s2, n); assert_int_equal(c1, c2); + n += 2; } while (c1); } @@ -82,23 +85,27 @@ static void test_managed_password_blob(void **state) const DATA_BLOB blob = {data, sizeof data}; /* The UTF‐16 password contained in the blob. */ - const uint16_t current_password[] = { - 16781, 38893, 3992, 51373, 15923, 7932, 46125, 2558, 34452, - 30290, 33629, 52175, 11237, 39662, 24149, 37397, 11132, 19333, - 4008, 61917, 9782, 34431, 59396, 14004, 57456, 4643, 36018, - 13809, 19377, 45615, 4500, 41906, 13134, 3922, 30149, 14594, - 62323, 37627, 63819, 14101, 32226, 28757, 21916, 10026, 4483, - 50729, 41961, 43820, 37254, 34397, 24410, 18164, 35324, 51276, - 5135, 22021, 60285, 770, 63905, 6660, 52725, 4490, 8697, - 38539, 36481, 5923, 48763, 22745, 32851, 6331, 17667, 14586, - 22153, 50590, 31390, 25994, 64532, 26985, 7286, 6379, 64476, - 11322, 59188, 19010, 55290, 24783, 14809, 6553, 1291, 20746, - 50886, 62962, 23379, 44922, 7754, 6910, 29146, 63937, 24509, - 38781, 60409, 17028, 43589, 36843, 39787, 8730, 7072, 20390, - 26656, 25846, 19514, 26258, 27121, 38664, 5283, 59418, 35361, - 47263, 48001, 31518, 4533, 21653, 63671, 65234, 25134, 3297, - 50225, 38336, 0, - }; + const unsigned char current_password[] = { + 141, 65, 237, 151, 152, 15, 173, 200, 51, 62, 252, 30, 45, + 180, 254, 9, 148, 134, 82, 118, 93, 131, 207, 203, 229, 43, + 238, 154, 85, 94, 21, 146, 124, 43, 133, 75, 168, 15, 221, + 241, 54, 38, 127, 134, 4, 232, 180, 54, 112, 224, 35, 18, + 178, 140, 241, 53, 177, 75, 47, 178, 148, 17, 178, 163, 78, + 51, 82, 15, 197, 117, 2, 57, 115, 243, 251, 146, 75, 249, + 21, 55, 226, 125, 85, 112, 156, 85, 42, 39, 131, 17, 41, + 198, 233, 163, 44, 171, 134, 145, 93, 134, 90, 95, 244, 70, + 252, 137, 76, 200, 15, 20, 5, 86, 125, 235, 2, 3, 161, + 249, 4, 26, 245, 205, 138, 17, 249, 33, 139, 150, 129, 142, + 35, 23, 123, 190, 217, 88, 83, 128, 187, 24, 3, 69, 250, + 56, 137, 86, 158, 197, 158, 122, 138, 101, 20, 252, 105, 105, + 118, 28, 235, 24, 220, 251, 58, 44, 52, 231, 66, 74, 250, + 215, 207, 96, 217, 57, 153, 25, 11, 5, 10, 81, 198, 198, + 242, 245, 83, 91, 122, 175, 74, 30, 254, 26, 218, 113, 193, + 249, 189, 95, 125, 151, 249, 235, 132, 66, 69, 170, 235, 143, + 107, 155, 26, 34, 160, 27, 166, 79, 32, 104, 246, 100, 58, + 76, 146, 102, 241, 105, 8, 151, 163, 20, 26, 232, 33, 138, + 159, 184, 129, 187, 30, 123, 181, 17, 149, 84, 183, 248, 210, + 254, 46, 98, 225, 12, 49, 196, 192, 149, 0, 0}; DATA_BLOB packed_blob = data_blob_null; diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm index 57f8e8b5638..c09ee4b784d 100644 --- a/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -1706,7 +1706,7 @@ sub ConvertU16StringFromPythonData($$$$$) $self->pidl("{"); $self->indent; - $self->pidl("uint16_t *str = NULL;"); + $self->pidl("unsigned char *str = NULL;"); $self->pidl(""); $self->pidl("str = PyUtf16String_FromBytes("); $self->pidl(" $mem_ctx, $py_var);"); diff --git a/pidl/lib/Parse/Pidl/Typelist.pm b/pidl/lib/Parse/Pidl/Typelist.pm index 09d416f7b20..31ea19e357c 100644 --- a/pidl/lib/Parse/Pidl/Typelist.pm +++ b/pidl/lib/Parse/Pidl/Typelist.pm @@ -56,7 +56,7 @@ my %scalars = ( "pointer" => "void*", "DATA_BLOB" => "DATA_BLOB", "string" => "const char *", - "u16string" => "const uint16_t *", + "u16string" => "const unsigned char *", "string_array" => "const char **", "time_t" => "time_t", "uid_t" => "uid_t", diff --git a/source4/librpc/rpc/pyrpc_util.c b/source4/librpc/rpc/pyrpc_util.c index 98cfb73c1af..43c29af0e76 100644 --- a/source4/librpc/rpc/pyrpc_util.c +++ b/source4/librpc/rpc/pyrpc_util.c @@ -419,7 +419,7 @@ PyObject *PyString_FromStringOrNULL(const char *str) return PyUnicode_FromString(str); } -PyObject *PyBytes_FromUtf16StringOrNULL(const uint16_t *str) +PyObject *PyBytes_FromUtf16StringOrNULL(const unsigned char *str) { size_t len; @@ -431,11 +431,11 @@ PyObject *PyBytes_FromUtf16StringOrNULL(const uint16_t *str) return PyBytes_FromStringAndSize((const char *)str, len); } -uint16_t *PyUtf16String_FromBytes(TALLOC_CTX *mem_ctx, PyObject *value) +unsigned char *PyUtf16String_FromBytes(TALLOC_CTX *mem_ctx, PyObject *value) { char *bytes = NULL; Py_ssize_t len = 0; - uint16_t *utf16_string = NULL; + unsigned char *utf16_string = NULL; int ret; ret = PyBytes_AsStringAndSize(value, &bytes, &len); diff --git a/source4/librpc/rpc/pyrpc_util.h b/source4/librpc/rpc/pyrpc_util.h index 75b04f1d5fe..73157fcba1c 100644 --- a/source4/librpc/rpc/pyrpc_util.h +++ b/source4/librpc/rpc/pyrpc_util.h @@ -59,9 +59,9 @@ PyObject *py_return_ndr_struct(const char *module_name, const char *type_name, PyObject *PyString_FromStringOrNULL(const char *str); -PyObject *PyBytes_FromUtf16StringOrNULL(const uint16_t *str); +PyObject *PyBytes_FromUtf16StringOrNULL(const unsigned char *str); -uint16_t *PyUtf16String_FromBytes(TALLOC_CTX *mem_ctx, PyObject *value); +unsigned char *PyUtf16String_FromBytes(TALLOC_CTX *mem_ctx, PyObject *value); PyObject *pyrpc_import_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level, const void *in, const char *typename);