diff options
author | Stefan Metzmacher <metze@samba.org> | 2014-01-03 09:25:23 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2014-01-07 00:27:11 +0100 |
commit | b62308ed994e9734dfd934d230531010d9e7cefa (patch) | |
tree | b93735a04d4f9333f8ee334b2220d1d04837c6eb | |
parent | 523d616268af5f94e11c863f9acdebabace80608 (diff) | |
download | samba-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>
-rw-r--r-- | librpc/idl/idl_types.h | 2 | ||||
-rw-r--r-- | librpc/ndr/libndr.h | 6 | ||||
-rw-r--r-- | librpc/ndr/ndr.c | 20 |
3 files changed, 28 insertions, 0 deletions
diff --git a/librpc/idl/idl_types.h b/librpc/idl/idl_types.h index c50eface0d1..838c2192515 100644 --- a/librpc/idl/idl_types.h +++ b/librpc/idl/idl_types.h @@ -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 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; } |