From: Ian Jackson Date: Sat, 3 Dec 2016 14:30:30 +0000 (+0000) Subject: SECURITY: pa_soa: Do not sign extend SOA 32-bit integer fields on 64-bit X-Git-Tag: adns-1.5.2~28 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=adns.git;a=commitdiff_plain;h=4c4071fbf5b7d5bbb030d38710db9c7810a2b8fa SECURITY: pa_soa: Do not sign extend SOA 32-bit integer fields on 64-bit The previous code used GET_W twice on two int variables, for no explicable reason. The top of these int variables was shifted left by 16, giving a 32-bit signed value. The fields in adns_rr_soa are unsigned long. On a 64-bit machine, the 32-bit signed value is implicitly sign extended. This is entirely wrong. Found by AFL 2.35b. Signed-off-by: Ian Jackson --- diff --git a/src/types.c b/src/types.c index 5e2bd14..d249ca2 100644 --- a/src/types.c +++ b/src/types.c @@ -1371,7 +1371,7 @@ static adns_status pa_soa(const parseinfo *pai, int cbyte, adns_rr_soa *rrp= datap; const byte *dgram= pai->dgram; adns_status st; - int msw, lsw, i; + int i; st= pap_domain(pai, &cbyte, max, &rrp->mname, pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0); @@ -1383,9 +1383,8 @@ static adns_status pa_soa(const parseinfo *pai, int cbyte, if (cbyte+20 != max) return adns_s_invaliddata; for (i=0; i<5; i++) { - GET_W(cbyte,msw); - GET_W(cbyte,lsw); - (&rrp->serial)[i]= (msw<<16) | lsw; + unsigned long v; + (&rrp->serial)[i]= GET_L(cbyte, v); } return adns_s_ok;