samba/backport-0002-CVE-2022-42898.patch
2022-11-22 11:12:39 +00:00

290 lines
7.7 KiB
Diff

From a1a2eeb278cd0b504c9229cd7152f74463232fc4 Mon Sep 17 00:00:00 2001
From: Nicolas Williams <nico@twosigma.com>
Date: Thu, 21 May 2015 14:24:38 -0500
Subject: [PATCH 2/4] CVE-2022-42898 source4/heimdal: Add
krb5_ret/store_[u]int64()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15203
[jsutton@samba.org backported from Heimdal commit
996d4c5db3c8aee10b7496591db13f52a575cef5; removed changes to
lib/krb5/libkrb5-exports.def.in which we don't have]
---
source4/heimdal/lib/krb5/store-int.c | 13 +-
source4/heimdal/lib/krb5/store.c | 132 +++++++++++++++++---
source4/heimdal/lib/krb5/version-script.map | 4 +
3 files changed, 133 insertions(+), 16 deletions(-)
diff --git a/source4/heimdal/lib/krb5/store-int.c b/source4/heimdal/lib/krb5/store-int.c
index d5776297181..542b99abc08 100644
--- a/source4/heimdal/lib/krb5/store-int.c
+++ b/source4/heimdal/lib/krb5/store-int.c
@@ -34,7 +34,7 @@
#include "krb5_locl.h"
KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
-_krb5_put_int(void *buffer, unsigned long value, size_t size)
+_krb5_put_int(void *buffer, uint64_t value, size_t size)
{
unsigned char *p = buffer;
int i;
@@ -46,7 +46,7 @@ _krb5_put_int(void *buffer, unsigned long value, size_t size)
}
KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
-_krb5_get_int(void *buffer, unsigned long *value, size_t size)
+_krb5_get_int64(void *buffer, uint64_t *value, size_t size)
{
unsigned char *p = buffer;
unsigned long v = 0;
@@ -56,3 +56,12 @@ _krb5_get_int(void *buffer, unsigned long *value, size_t size)
*value = v;
return size;
}
+
+KRB5_LIB_FUNCTION krb5_ssize_t KRB5_LIB_CALL
+_krb5_get_int(void *buffer, unsigned long *value, size_t size)
+{
+ uint64_t v64;
+ krb5_ssize_t bytes = _krb5_get_int64(buffer, &v64, size);
+ *value = v64;
+ return bytes;
+}
diff --git a/source4/heimdal/lib/krb5/store.c b/source4/heimdal/lib/krb5/store.c
index 31afb23c983..df0227b39de 100644
--- a/source4/heimdal/lib/krb5/store.c
+++ b/source4/heimdal/lib/krb5/store.c
@@ -318,13 +318,13 @@ krb5_storage_to_data(krb5_storage *sp, krb5_data *data)
static krb5_error_code
krb5_store_int(krb5_storage *sp,
- int32_t value,
+ int64_t value,
size_t len)
{
int ret;
- unsigned char v[16];
+ unsigned char v[8];
- if(len > sizeof(v))
+ if (len > sizeof(v))
return EINVAL;
_krb5_put_int(v, value, len);
ret = sp->store(sp, v, len);
@@ -358,6 +358,33 @@ krb5_store_int32(krb5_storage *sp,
return krb5_store_int(sp, value, 4);
}
+/**
+ * Store a int64 to storage, byte order is controlled by the settings
+ * on the storage, see krb5_storage_set_byteorder().
+ *
+ * @param sp the storage to write too
+ * @param value the value to store
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_store_int64(krb5_storage *sp,
+ int64_t value)
+{
+ if (BYTEORDER_IS_HOST(sp))
+#ifdef WORDS_BIGENDIAN
+ ;
+#else
+ value = bswap64(value); /* There's no ntohll() */
+#endif
+ else if (BYTEORDER_IS_LE(sp))
+ value = bswap64(value);
+ return krb5_store_int(sp, value, 8);
+}
+
/**
* Store a uint32 to storage, byte order is controlled by the settings
* on the storage, see krb5_storage_set_byteorder().
@@ -377,24 +404,99 @@ krb5_store_uint32(krb5_storage *sp,
return krb5_store_int32(sp, (int32_t)value);
}
+/**
+ * Store a uint64 to storage, byte order is controlled by the settings
+ * on the storage, see krb5_storage_set_byteorder().
+ *
+ * @param sp the storage to write too
+ * @param value the value to store
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_store_uint64(krb5_storage *sp,
+ uint64_t value)
+{
+ return krb5_store_int64(sp, (int64_t)value);
+}
+
static krb5_error_code
krb5_ret_int(krb5_storage *sp,
- int32_t *value,
+ int64_t *value,
size_t len)
{
int ret;
- unsigned char v[4];
- unsigned long w;
+ unsigned char v[8];
+ uint64_t w;
ret = sp->fetch(sp, v, len);
if (ret < 0)
return errno;
if ((size_t)ret != len)
return sp->eof_code;
- _krb5_get_int(v, &w, len);
+ _krb5_get_int64(v, &w, len);
*value = w;
return 0;
}
+/**
+ * Read a int64 from storage, byte order is controlled by the settings
+ * on the storage, see krb5_storage_set_byteorder().
+ *
+ * @param sp the storage to write too
+ * @param value the value read from the buffer
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_ret_int64(krb5_storage *sp,
+ int64_t *value)
+{
+ krb5_error_code ret = krb5_ret_int(sp, value, 8);
+ if(ret)
+ return ret;
+ if(BYTEORDER_IS_HOST(sp))
+#ifdef WORDS_BIGENDIAN
+ ;
+#else
+ *value = bswap64(*value); /* There's no ntohll() */
+#endif
+ else if(BYTEORDER_IS_LE(sp))
+ *value = bswap64(*value);
+ return 0;
+}
+
+/**
+ * Read a uint64 from storage, byte order is controlled by the settings
+ * on the storage, see krb5_storage_set_byteorder().
+ *
+ * @param sp the storage to write too
+ * @param value the value read from the buffer
+ *
+ * @return 0 for success, or a Kerberos 5 error code on failure.
+ *
+ * @ingroup krb5_storage
+ */
+
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
+krb5_ret_uint64(krb5_storage *sp,
+ uint64_t *value)
+{
+ krb5_error_code ret;
+ int64_t v;
+
+ ret = krb5_ret_int64(sp, &v);
+ if (ret == 0)
+ *value = (uint64_t)v;
+
+ return ret;
+}
+
/**
* Read a int32 from storage, byte order is controlled by the settings
* on the storage, see krb5_storage_set_byteorder().
@@ -411,12 +513,15 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_int32(krb5_storage *sp,
int32_t *value)
{
- krb5_error_code ret = krb5_ret_int(sp, value, 4);
- if(ret)
+ int64_t v;
+
+ krb5_error_code ret = krb5_ret_int(sp, &v, 4);
+ if (ret)
return ret;
- if(BYTEORDER_IS_HOST(sp))
+ *value = v;
+ if (BYTEORDER_IS_HOST(sp))
*value = htonl(*value);
- else if(BYTEORDER_IS_LE(sp))
+ else if (BYTEORDER_IS_LE(sp))
*value = bswap32(*value);
return 0;
}
@@ -434,8 +539,7 @@ krb5_ret_int32(krb5_storage *sp,
*/
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
-krb5_ret_uint32(krb5_storage *sp,
- uint32_t *value)
+krb5_ret_uint32(krb5_storage *sp, uint32_t *value)
{
krb5_error_code ret;
int32_t v;
@@ -505,7 +609,7 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_ret_int16(krb5_storage *sp,
int16_t *value)
{
- int32_t v = 0;
+ int64_t v;
int ret;
ret = krb5_ret_int(sp, &v, 2);
if(ret)
diff --git a/source4/heimdal/lib/krb5/version-script.map b/source4/heimdal/lib/krb5/version-script.map
index 2359001e9da..d0412c08d59 100644
--- a/source4/heimdal/lib/krb5/version-script.map
+++ b/source4/heimdal/lib/krb5/version-script.map
@@ -550,6 +550,7 @@ HEIMDAL_KRB5_2.0 {
krb5_ret_data;
krb5_ret_int16;
krb5_ret_int32;
+ krb5_ret_int64;
krb5_ret_int8;
krb5_ret_keyblock;
krb5_ret_principal;
@@ -559,6 +560,7 @@ HEIMDAL_KRB5_2.0 {
krb5_ret_times;
krb5_ret_uint16;
krb5_ret_uint32;
+ krb5_ret_uint64;
krb5_ret_uint8;
krb5_salttype_to_string;
krb5_sendauth;
@@ -623,6 +625,7 @@ HEIMDAL_KRB5_2.0 {
krb5_store_data;
krb5_store_int16;
krb5_store_int32;
+ krb5_store_int64;
krb5_store_int8;
krb5_store_keyblock;
krb5_store_principal;
@@ -632,6 +635,7 @@ HEIMDAL_KRB5_2.0 {
krb5_store_times;
krb5_store_uint16;
krb5_store_uint32;
+ krb5_store_uint64;
krb5_store_uint8;
krb5_string_to_deltat;
krb5_string_to_enctype;
--
2.35.0