From: Douglas Bagnall Date: Fri, 13 Mar 2026 02:16:09 +0000 (+1300) Subject: ndr:witness: ensure notifyResponse messages have size X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f2e55d14bbb00dc9d3ca00c5503aee262402942;p=thirdparty%2Fsamba.git ndr:witness: ensure notifyResponse messages have size 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 Reviewed-by: Jennifer Sutton Autobuild-User(master): Gary Lockyer Autobuild-Date(master): Thu May 28 00:33:53 UTC 2026 on atb-devel-224 --- diff --git a/librpc/ndr/ndr_witness.c b/librpc/ndr/ndr_witness.c index 85ba62ea774..11bd42269cc 100644 --- a/librpc/ndr/ndr_witness.c +++ b/librpc/ndr/ndr_witness.c @@ -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 index 2dfe89a149e..00000000000 --- a/selftest/knownfail.d/witness +++ /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\)