librpc/ndr: add LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES
authorStefan Metzmacher <metze@samba.org>
Fri, 3 Jan 2014 08:25:23 +0000 (09:25 +0100)
committerStefan Metzmacher <metze@samba.org>
Mon, 6 Jan 2014 23:27:11 +0000 (00:27 +0100)
This lets ndr_pull_subcontext_end() make sure that all
subcontext bytes are consumed otherwise it returns NDR_ERR_UNREAD_BYTES.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
librpc/idl/idl_types.h
librpc/ndr/libndr.h
librpc/ndr/ndr.c

index c50eface0d1282d311bd82602e07ca36a380bcc5..838c21925150c0c29a9ad5a5ce9ce37f5b13ec3c 100644 (file)
@@ -53,3 +53,5 @@
 
 #define NDR_RELATIVE_REVERSE LIBNDR_FLAG_RELATIVE_REVERSE
 #define NDR_NO_RELATIVE_REVERSE LIBNDR_FLAG_NO_RELATIVE_REVERSE
+
+#define NDR_SUBCONTEXT_NO_UNREAD_BYTES LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES
index a95051905709a8acf69ecb0cf526b842a720aceb..8070c3cb56f24b78a1d1d41cc18c8073f141c1e7 100644 (file)
@@ -123,6 +123,12 @@ struct ndr_print {
 #define LIBNDR_FLAG_STR_RAW8           (1<<13)
 #define LIBNDR_STRING_FLAGS            (0x7FFC)
 
+/*
+ * This lets ndr_pull_subcontext_end() return
+ * NDR_ERR_UNREAD_BYTES.
+ */
+#define LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES (1<<17)
+
 /* set if relative pointers should *not* be marshalled in reverse order */
 #define LIBNDR_FLAG_NO_RELATIVE_REVERSE        (1<<18)
 
index e86cf2f7635119e0e3e40865cc83d75074ec1fa4..15a7f12bb61e571a7e7955f8403dda41979ea294 100644 (file)
@@ -638,6 +638,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subcontext_end(struct ndr_pull *ndr,
                                 ssize_t size_is)
 {
        uint32_t advance;
+       uint32_t highest_ofs;
+
        if (size_is >= 0) {
                advance = size_is;
        } else if (header_size > 0) {
@@ -645,6 +647,24 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subcontext_end(struct ndr_pull *ndr,
        } else {
                advance = subndr->offset;
        }
+
+       if (subndr->offset > ndr->relative_highest_offset) {
+               highest_ofs = subndr->offset;
+       } else {
+               highest_ofs = subndr->relative_highest_offset;
+       }
+       if (!(subndr->flags & LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES)) {
+               /*
+                * avoid an error unless SUBCONTEXT_NO_UNREAD_BYTES is specified
+                */
+               highest_ofs = advance;
+       }
+       if (highest_ofs < advance) {
+               return ndr_pull_error(subndr, NDR_ERR_UNREAD_BYTES,
+                                     "not all bytes consumed ofs[%u] advance[%u]",
+                                     highest_ofs, advance);
+       }
+
        NDR_CHECK(ndr_pull_advance(ndr, advance));
        return NDR_ERR_SUCCESS;
 }