librpc: add SMB_ASSERT(blob->length >= DCERPC_NCACN_PAYLOAD_OFFSET) protection
authorStefan Metzmacher <metze@samba.org>
Mon, 24 Dec 2018 10:21:38 +0000 (11:21 +0100)
committerJeremy Allison <jra@samba.org>
Sat, 12 Jan 2019 02:13:31 +0000 (03:13 +0100)
A lot of functions rely on having the 16 bytes dcerpc header to operate
on. This makes it more obvious and makes sure they can't be misused in
future.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
librpc/rpc/dcerpc_util.c

index e0479c2f36b1aea81a1536937f4f726080dab69e..6bc97f7e7d82e04a153acfc219a8eb6b29092b79 100644 (file)
@@ -34,6 +34,8 @@
    decode */
 void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v)
 {
+       SMB_ASSERT(blob->length >= DCERPC_NCACN_PAYLOAD_OFFSET);
+
        if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
                SSVAL(blob->data, DCERPC_FRAG_LEN_OFFSET, v);
        } else {
@@ -43,6 +45,8 @@ void dcerpc_set_frag_length(DATA_BLOB *blob, uint16_t v)
 
 uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob)
 {
+       SMB_ASSERT(blob->length >= DCERPC_NCACN_PAYLOAD_OFFSET);
+
        if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
                return SVAL(blob->data, DCERPC_FRAG_LEN_OFFSET);
        } else {
@@ -52,6 +56,8 @@ uint16_t dcerpc_get_frag_length(const DATA_BLOB *blob)
 
 void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v)
 {
+       SMB_ASSERT(blob->length >= DCERPC_NCACN_PAYLOAD_OFFSET);
+
        if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
                SSVAL(blob->data, DCERPC_AUTH_LEN_OFFSET, v);
        } else {
@@ -61,6 +67,8 @@ void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v)
 
 uint16_t dcerpc_get_auth_length(const DATA_BLOB *blob)
 {
+       SMB_ASSERT(blob->length >= DCERPC_NCACN_PAYLOAD_OFFSET);
+
        if (CVAL(blob->data,DCERPC_DREP_OFFSET) & DCERPC_DREP_LE) {
                return SVAL(blob->data, DCERPC_AUTH_LEN_OFFSET);
        } else {
@@ -70,6 +78,8 @@ uint16_t dcerpc_get_auth_length(const DATA_BLOB *blob)
 
 uint8_t dcerpc_get_endian_flag(DATA_BLOB *blob)
 {
+       SMB_ASSERT(blob->length >= DCERPC_NCACN_PAYLOAD_OFFSET);
+
        return blob->data[DCERPC_DREP_OFFSET];
 }