librpc:ndr: Fix undefined behavior in ndr_basic
authorAndreas Schneider <asn@samba.org>
Thu, 22 Nov 2018 14:15:03 +0000 (15:15 +0100)
committerGary Lockyer <gary@samba.org>
Thu, 6 Dec 2018 07:48:27 +0000 (08:48 +0100)
librpc/ndr/ndr_basic.c:723:2: runtime error: null pointer passed as
argument 2, which is declared to never be null

The following triggered the undefined behavior:

(gdb) bt
    at librpc/gen_ndr/ndr_drsuapi.c:2318
    fn=0x7ffff6e72983 <ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary>) at ../../librpc/ndr/ndr.c:1337
    at ../../source4/dsdb/schema/schema_syntax.c:2136
    drs_str=<optimized out>) at ../../source4/dsdb/schema/tests/schema_syntax.c:122
    already_setup=<optimized out>, restricted=restricted@entry=0x0) at ../../lib/torture/torture.c:442
    at ../../lib/torture/torture.c:507
    suite=0x5555563d9490, matched=0x7fffffffcef7) at ../../source4/torture/smbtorture.c:93
    matched=0x7fffffffcef7) at ../../source4/torture/smbtorture.c:95
    at ../../source4/torture/smbtorture.c:143
(gdb) f 1
1335            NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
(gdb) p blob
$2 = {data = 0x0, length = 0}

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
Autobuild-User(master): Gary Lockyer <gary@samba.org>
Autobuild-Date(master): Thu Dec  6 08:48:28 CET 2018 on sn-devel-144

librpc/ndr/ndr_basic.c

index c874f340388e006cf05a773e3d208fb44f65ad72..b488c7c22d9d9ef9d7a0a3396188db6020e0cf57 100644 (file)
@@ -719,6 +719,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_trailer_align(struct ndr_pull *ndr, size_t s
 */
 _PUBLIC_ enum ndr_err_code ndr_push_bytes(struct ndr_push *ndr, const uint8_t *data, uint32_t n)
 {
+       if (n == 0) {
+               return NDR_ERR_SUCCESS;
+       }
+       if (data == NULL) {
+               return NDR_ERR_INVALID_POINTER;
+       }
        NDR_PUSH_NEED_BYTES(ndr, n);
        memcpy(ndr->data + ndr->offset, data, n);
        ndr->offset += n;
@@ -1329,6 +1335,10 @@ _PUBLIC_ enum ndr_err_code ndr_push_DATA_BLOB(struct ndr_push *ndr, int ndr_flag
        } else {
                NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, blob.length));
        }
+       if (blob.length == 0) {
+               return NDR_ERR_SUCCESS;
+       }
+
        NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
        return NDR_ERR_SUCCESS;
 }