summaryrefslogtreecommitdiffstats
path: root/librpc/ndr
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2014-01-03 09:25:23 +0100
committerStefan Metzmacher <metze@samba.org>2014-01-07 00:27:11 +0100
commitb62308ed994e9734dfd934d230531010d9e7cefa (patch)
treeb93735a04d4f9333f8ee334b2220d1d04837c6eb /librpc/ndr
parent523d616268af5f94e11c863f9acdebabace80608 (diff)
downloadsamba-b62308ed994e9734dfd934d230531010d9e7cefa.tar.gz
samba-b62308ed994e9734dfd934d230531010d9e7cefa.tar.xz
samba-b62308ed994e9734dfd934d230531010d9e7cefa.zip
librpc/ndr: add LIBNDR_FLAG_SUBCONTEXT_NO_UNREAD_BYTES
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>
Diffstat (limited to 'librpc/ndr')
-rw-r--r--librpc/ndr/libndr.h6
-rw-r--r--librpc/ndr/ndr.c20
2 files changed, 26 insertions, 0 deletions
diff --git a/librpc/ndr/libndr.h b/librpc/ndr/libndr.h
index a9505190570..8070c3cb56f 100644
--- a/librpc/ndr/libndr.h
+++ b/librpc/ndr/libndr.h
@@ -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)
diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c
index e86cf2f7635..15a7f12bb61 100644
--- a/librpc/ndr/ndr.c
+++ b/librpc/ndr/ndr.c
@@ -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;
}