From b62308ed994e9734dfd934d230531010d9e7cefa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 3 Jan 2014 09:25:23 +0100 Subject: 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 Reviewed-by: Andrew Bartlett --- librpc/ndr/libndr.h | 6 ++++++ librpc/ndr/ndr.c | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) (limited to 'librpc/ndr') 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; } -- cgit