The branch, master has been updated
via f1a82801692 librpc:bcrypt_rsakey_blob: exponent and modulus lengths
can't be zero
from c1ee6fe9a48 s3/libsmb: check the negative-conn-cache in
resolve_ads()
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit f1a828016921b4d5852148cdb2b8147ceafd7f69
Author: Douglas Bagnall <[email protected]>
Date: Wed Jul 30 21:18:09 2025 +1200
librpc:bcrypt_rsakey_blob: exponent and modulus lengths can't be zero
Apart from it making no sense, without these ranges we end up
allocating a NULL buffer and aborting.
We also put a maximum size on the RSA key, in case we could get
tricked into a DoS by pulling a large buffer and trying crypto maths
on it.
6 0x572ebce2749a in talloc_abort samba/lib/talloc/talloc.c:506:3
7 0x572ebce271d4 in talloc_chunk_from_ptr samba/lib/talloc/talloc.c:0
8 0x572ebce271d4 in __talloc_with_prefix samba/lib/talloc/talloc.c:762:12
9 0x572ebce235f9 in __talloc samba/lib/talloc/talloc.c:825:9
10 0x572ebce235f9 in _talloc_named_const samba/lib/talloc/talloc.c:982:8
11 0x572ebce235f9 in _talloc_memdup samba/lib/talloc/talloc.c:2441:9
12 0x572ebc8f6a4f in data_blob_talloc_named samba/lib/util/data_blob.c:56:25
13 0x572ebc7d23bd in pull_BCRYPT_RSAPUBLIC_BLOB
samba/librpc/ndr/ndr_keycredlink.c:878:17
14 0x572ebc7d23bd in ndr_pull_KeyMaterialInternal
samba/librpc/ndr/ndr_keycredlink.c:959:10
15 0x572ebc788e90 in LLVMFuzzerTestOneInput
samba/bin/default/lib/fuzzing/fuzz_ndr_keycredlink_TYPE_STRUCT.c:282:13
REF: https://issues.oss-fuzz.com/issues/435039896
Signed-off-by: Douglas Bagnall <[email protected]>
Reviewed-by: Gary Lockyer <[email protected]>
Autobuild-User(master): Douglas Bagnall <[email protected]>
Autobuild-Date(master): Thu Jul 31 05:45:07 UTC 2025 on atb-devel-224
-----------------------------------------------------------------------
Summary of changes:
librpc/idl/bcrypt_rsakey_blob.idl | 15 ++++++++--
python/samba/tests/bcrypt_rsakey_blob.py | 51 ++++++++++++++------------------
2 files changed, 35 insertions(+), 31 deletions(-)
Changeset truncated at 500 lines:
diff --git a/librpc/idl/bcrypt_rsakey_blob.idl
b/librpc/idl/bcrypt_rsakey_blob.idl
index fd5f6134e34..6bd071cf4d4 100644
--- a/librpc/idl/bcrypt_rsakey_blob.idl
+++ b/librpc/idl/bcrypt_rsakey_blob.idl
@@ -21,13 +21,22 @@ interface bcrypt_rsakey_blob
/* Currently only handle RSA Public Key blobs */
[value(0x31415352), range(0x31415352, 0x31415352)]
uint32 magic; /* RSA1 */
- uint32 bit_length;
+ /*
+ * In key_credential_links we expect bit_length to be
+ * 2048, but we accept a wider range in part because
+ * testing is much easier with small numbers.
+ */
+ [range(1,65536)]uint32 bit_length;
/*
* As of Windows 10 version 1903, public exponents larger
* than (2^64 - 1) are no longer supported.
*/
- [range(0x0,0x8)] uint32 public_exponent_len;
- uint32 modulus_len;
+ [range(0x1,0x8)] uint32 public_exponent_len;
+ /*
+ * modulus_len is the key size in bytes, more or less
+ * bit_length / 8.
+ */
+ [range(0x1, 0x2001)] uint32 modulus_len;
/*
* We're only supporting public keys, so the private
* key prime lengths should be zero
diff --git a/python/samba/tests/bcrypt_rsakey_blob.py
b/python/samba/tests/bcrypt_rsakey_blob.py
index ea984445d24..59e446deec2 100755
--- a/python/samba/tests/bcrypt_rsakey_blob.py
+++ b/python/samba/tests/bcrypt_rsakey_blob.py
@@ -35,7 +35,8 @@ class BcryptRsaKeyBlobTests(TestCase):
def test_unpack_empty_key_blob(self):
"""
Ensure that a minimal header only BCRYPT_RSAPUBLIC_BLOB
- can be unpacked, then packed into identical bytes
+ can't be unpacked, because it would imply zero length modulus
+ and exponent numbers, which is meaningless.
"""
empty_key_blob = bytes.fromhex(
"52 53 41 31" # Magic value RSA1
@@ -45,20 +46,11 @@ class BcryptRsaKeyBlobTests(TestCase):
"00 00 00 00" # prime one length"
"00 00 00 00" # prime two length"
)
- blob = ndr_unpack(
- bcrypt_rsakey_blob.BCRYPT_RSAPUBLIC_BLOB, empty_key_blob)
-
- self.assertEqual(blob.magic, 0x31415352)
- self.assertEqual(blob.bit_length, 0)
- self.assertEqual(blob.public_exponent_len, 0)
- self.assertEqual(blob.modulus_len, 0)
- self.assertEqual(blob.prime1_len_unused, 0)
- self.assertEqual(blob.prime2_len_unused, 0)
- self.assertEqual(len(blob.public_exponent), 0)
- self.assertEqual(len(blob.modulus), 0)
-
- packed = ndr_pack(blob)
- self.assertEqual(empty_key_blob, packed)
+ with self.assertRaises(RuntimeError) as e:
+ ndr_unpack(bcrypt_rsakey_blob.BCRYPT_RSAPUBLIC_BLOB,
+ empty_key_blob)
+ self.assertEqual(e.exception.args[0], 13)
+ self.assertEqual(e.exception.args[1], "Range Error")
def test_unpack_invalid_magic(self):
"""
@@ -67,11 +59,12 @@ class BcryptRsaKeyBlobTests(TestCase):
"""
invalid_magic_key_blob = bytes.fromhex(
"52 53 41 30" # Magic value RSA0
- "00 00 00 00" # bit length
- "00 00 00 00" # public exponent length
- "00 00 00 00" # modulus length
+ "04 00 00 00" # bit length
+ "01 00 00 00" # public exponent length
+ "01 00 00 00" # modulus length
"00 00 00 00" # prime one length
"00 00 00 00" # prime two length"
+ "01 02" # exponent and modulus, one byte each
)
with self.assertRaises(RuntimeError) as e:
ndr_unpack(bcrypt_rsakey_blob.BCRYPT_RSAPUBLIC_BLOB,
@@ -87,11 +80,12 @@ class BcryptRsaKeyBlobTests(TestCase):
"""
extra_data_key_blob = bytes.fromhex(
"52 53 41 31" # Magic value RSA1
- "00 00 00 00" # bit length
- "00 00 00 00" # public exponent length
- "00 00 00 00" # modulus length
+ "04 00 00 00" # bit length
+ "01 00 00 00" # public exponent length
+ "01 00 00 00" # modulus length
"00 00 00 00" # prime one length
"00 00 00 00" # prime two length
+ "01 02" # exponent and modulus, one byte each
"01" # a trailing byte of data
)
with self.assertRaises(RuntimeError) as e:
@@ -127,9 +121,9 @@ class BcryptRsaKeyBlobTests(TestCase):
"""
invalid_magic_key_blob = bytes.fromhex(
"52 53 41 31" # Magic value RSA1
- "00 00 00 00" # bit length
+ "08 00 00 00" # bit length
"09 00 00 00" # public exponent length, 9 bytes
- "00 00 00 00" # modulus length
+ "01 00 00 00" # modulus length
"00 00 00 00" # prime one length
"00 00 00 00" # prime two length"
)
@@ -147,11 +141,12 @@ class BcryptRsaKeyBlobTests(TestCase):
"""
invalid_prime1_key_blob = bytes.fromhex(
"52 53 41 31" # Magic value RSA1
- "00 00 00 00" # bit length
- "00 00 00 00" # public exponent length, 9 bytes
- "00 00 00 00" # modulus length
+ "04 00 00 00" # bit length
+ "01 00 00 00" # public exponent length
+ "01 00 00 00" # modulus length
"01 00 00 00" # prime one length
"00 00 00 00" # prime two length"
+ "01 02" # exponent and modulus, one byte each
)
with self.assertRaises(RuntimeError) as e:
ndr_unpack(bcrypt_rsakey_blob.BCRYPT_RSAPUBLIC_BLOB,
@@ -168,8 +163,8 @@ class BcryptRsaKeyBlobTests(TestCase):
invalid_prime2_key_blob = bytes.fromhex(
"52 53 41 31" # Magic value RSA1
"00 00 00 00" # bit length
- "00 00 00 00" # public exponent length, 9 bytes
- "00 00 00 00" # modulus length
+ "01 00 00 00" # public exponent length
+ "01 00 00 00" # modulus length
"00 00 00 00" # prime one length
"01 00 00 00" # prime two length"
)
--
Samba Shared Repository