]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ndr:witness: ensure notifyResponse messages have size
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Fri, 13 Mar 2026 02:16:09 +0000 (15:16 +1300)
committerGary Lockyer <gary@samba.org>
Thu, 28 May 2026 00:33:53 +0000 (00:33 +0000)
If the type is message unknown, we look to read messages as data blobs
but if there is no data remaining, the blob is empty and the ndr
offset does not advance. This result in a potentially very long loop
from a tiny packet, expanding into many empty blobs.

With this we require that a message absorbs at least some NDR bytes.

REF: https://issues.oss-fuzz.com/issues/482968113

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Jennifer Sutton <jennifersutton@catalyst.net.nz>
Autobuild-User(master): Gary Lockyer <gary@samba.org>
Autobuild-Date(master): Thu May 28 00:33:53 UTC 2026 on atb-devel-224

librpc/ndr/ndr_witness.c
selftest/knownfail.d/witness [deleted file]

index 85ba62ea774d5b37a35feb60aa3092e792a8ae3f..11bd42269cc9822e1af749cc6c02466dae34a4de 100644 (file)
@@ -91,8 +91,54 @@ _PUBLIC_ enum ndr_err_code ndr_pull_witness_notifyResponse(struct ndr_pull *ndr,
                                        struct ndr_pull *_ndr_messages;
                                        NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_messages, 4, r->length));
                                        for (cntr_messages_0 = 0; cntr_messages_0 < (size_messages_0); cntr_messages_0++) {
+                                               uint32_t old_offset = _ndr_messages->offset;
                                                NDR_CHECK(ndr_pull_set_switch_value(_ndr_messages, &r->messages[cntr_messages_0], r->type));
                                                NDR_CHECK(ndr_pull_witness_notifyResponse_message(_ndr_messages, NDR_SCALARS, &r->messages[cntr_messages_0]));
+                                               if (_ndr_messages->offset == old_offset) {
+                                                       /*
+                                                        * We pulled
+                                                        * no data,
+                                                        * probably
+                                                        * because the
+                                                        * message
+                                                        * type was
+                                                        * nonsensical
+                                                        * and we
+                                                        * tried
+                                                        * pulling a
+                                                        * data blob
+                                                        * of zero
+                                                        * size which
+                                                        * leaves the
+                                                        * offset
+                                                        * unchanged.
+                                                        * The loop
+                                                        * will stop
+                                                        * when we get
+                                                        * to r->num,
+                                                        * but the
+                                                        * offset will
+                                                        * never
+                                                        * advance
+                                                        * past here.
+                                                        *
+                                                        * Otherwise,
+                                                        * we fill
+                                                        * this struct
+                                                        * with empty
+                                                        * messages:
+                                                        *
+                                                        * *r = {
+                                                        *    type = 7416864,
+                                                        *    length = 4,
+                                                        *    num = 10551297,
+                                                        *    messages = 0x...
+                                                        * }
+                                                        */
+                                                       ndr->flags = _flags_save_witness_notifyResponse_message;
+                                                       NDR_PULL_SET_MEM_CTX(ndr, _mem_save_messages_0, 0);
+                                                       return NDR_ERR_BAD_SWITCH;
+                                               }
                                        }
                                        NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_messages, 4, r->length));
                                }
diff --git a/selftest/knownfail.d/witness b/selftest/knownfail.d/witness
deleted file mode 100644 (file)
index 2dfe89a..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-^samba4\.local\.ndr\.witness\.witness_notifyResponse\.witness_notifyResponse_data_fuzz2_STRUCT\(none\)
-^samba4\.local\.ndr\.system\.iconv\.witness\.witness_notifyResponse\.witness_notifyResponse_data_fuzz2_STRUCT\(none\)