summaryrefslogtreecommitdiff
path: root/librpc/ndr
diff options
context:
space:
mode:
authorKai Blin <kai@samba.org>2010-09-30 20:35:00 -0700
committerKai Blin <kai@samba.org>2010-10-23 10:17:06 +0000
commita6305c4a168e7d3ac06f824dce05767bc7e9b9c0 (patch)
treec39d6194d08190fd5dd3712fca80a04ca066fa8c /librpc/ndr
parent69a52290ce81c62f1d6af717c4bd9b6281f0886f (diff)
downloadsamba-a6305c4a168e7d3ac06f824dce05767bc7e9b9c0.tar.gz
samba-a6305c4a168e7d3ac06f824dce05767bc7e9b9c0.tar.bz2
samba-a6305c4a168e7d3ac06f824dce05767bc7e9b9c0.zip
s4 dns: Better error handling when parsing invalid or unknown records
Diffstat (limited to 'librpc/ndr')
-rw-r--r--librpc/ndr/ndr_dns.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/librpc/ndr/ndr_dns.c b/librpc/ndr/ndr_dns.c
index 4f39eb4e67..ee2f1ce5cf 100644
--- a/librpc/ndr/ndr_dns.c
+++ b/librpc/ndr/ndr_dns.c
@@ -220,9 +220,14 @@ _PUBLIC_ enum ndr_err_code ndr_push_dns_res_rec(struct ndr_push *ndr, int ndr_fl
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ttl));
_saved_offset1 = ndr->offset;
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 0));
- NDR_CHECK(ndr_push_set_switch_value(ndr, &r->rdata, r->rr_type));
- NDR_CHECK(ndr_push_dns_rdata(ndr, NDR_SCALARS, &r->rdata));
-
+ if (r->length > 0) {
+ NDR_CHECK(ndr_push_set_switch_value(ndr, &r->rdata, r->rr_type));
+ NDR_CHECK(ndr_push_dns_rdata(ndr, NDR_SCALARS, &r->rdata));
+ if (r->unexpected.length > 0) {
+ return ndr_push_error(ndr, NDR_ERR_LENGTH,
+ "Invalid...Unexpected blob lenght is too large");
+ }
+ }
if (r->unexpected.length > UINT16_MAX) {
return ndr_push_error(ndr, NDR_ERR_LENGTH,
"Unexpected blob lenght is too large");
@@ -260,8 +265,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_dns_res_rec(struct ndr_pull *ndr, int ndr_fl
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->ttl));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->length));
_saved_offset1 = ndr->offset;
- NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->rdata, r->rr_type));
- NDR_CHECK(ndr_pull_dns_rdata(ndr, NDR_SCALARS, &r->rdata));
+ if (r->length > 0) {
+ NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->rdata, r->rr_type));
+ NDR_CHECK(ndr_pull_dns_rdata(ndr, NDR_SCALARS, &r->rdata));
+ } else {
+ ZERO_STRUCT(r->rdata);
+ }
length = ndr->offset - _saved_offset1;
if (length > r->length) {
return ndr_pull_error(ndr, NDR_ERR_LENGTH,