libsec: fix memory leaks in seq_decode() and octet_decode() of asn1 parser

This commit is contained in:
cinap_lenrek 2014-02-28 18:54:56 +01:00
parent 6354bd0728
commit bc137696be

View file

@ -261,11 +261,9 @@ ber_decode(uchar** pp, uchar* pend, Elem* pelem)
if(err == ASN_OK) { if(err == ASN_OK) {
err = length_decode(pp, pend, &length); err = length_decode(pp, pend, &length);
if(err == ASN_OK) { if(err == ASN_OK) {
if(tag.class == Universal) { if(tag.class == Universal)
err = value_decode(pp, pend, length, tag.num, isconstr, &val); err = value_decode(pp, pend, length, tag.num, isconstr, &val);
if(val.tag == VSeq || val.tag == VSet) else
setmalloctag(val.u.seqval, getcallerpc(&pp));
}else
err = value_decode(pp, pend, length, OCTET_STRING, 0, &val); err = value_decode(pp, pend, length, OCTET_STRING, 0, &val);
if(err == ASN_OK) { if(err == ASN_OK) {
pelem->tag = tag; pelem->tag = tag;
@ -400,8 +398,7 @@ value_decode(uchar** pp, uchar* pend, int length, int kind, int isconstr, Value*
pval->u.bitstringval = makebits(0, 0, 0); pval->u.bitstringval = makebits(0, 0, 0);
p += 2; p += 2;
} }
else else /* TODO: recurse and concat results */
/* TODO: recurse and concat results */
err = ASN_EUNIMPL; err = ASN_EUNIMPL;
} }
else { else {
@ -502,7 +499,6 @@ value_decode(uchar** pp, uchar* pend, int length, int kind, int isconstr, Value*
case SEQUENCE: case SEQUENCE:
err = seq_decode(&p, pend, length, isconstr, &vl); err = seq_decode(&p, pend, length, isconstr, &vl);
setmalloctag(vl, getcallerpc(&pp));
if(err == ASN_OK) { if(err == ASN_OK) {
pval->tag = VSeq ; pval->tag = VSeq ;
pval->u.seqval = vl; pval->u.seqval = vl;
@ -511,7 +507,6 @@ value_decode(uchar** pp, uchar* pend, int length, int kind, int isconstr, Value*
case SETOF: case SETOF:
err = seq_decode(&p, pend, length, isconstr, &vl); err = seq_decode(&p, pend, length, isconstr, &vl);
setmalloctag(vl, getcallerpc(&pp));
if(err == ASN_OK) { if(err == ASN_OK) {
pval->tag = VSet; pval->tag = VSet;
pval->u.setval = vl; pval->u.setval = vl;
@ -665,25 +660,27 @@ octet_decode(uchar** pp, uchar* pend, int length, int isconstr, Bytes** pbytes)
switch(elem.val.tag) { switch(elem.val.tag) {
case VOctets: case VOctets:
newans = catbytes(ans, elem.val.u.octetsval); newans = catbytes(ans, elem.val.u.octetsval);
freevalfields(&elem.val);
freebytes(ans); freebytes(ans);
ans = newans; ans = newans;
break; break;
case VEOC: case VEOC:
if(length != -1) { if(length == -1)
p = pold;
err = ASN_EINVAL;
}
goto cloop_done; goto cloop_done;
/* no break */
default: default:
freevalfields(&elem.val);
p = pold; p = pold;
err = ASN_EINVAL; err = ASN_EINVAL;
goto cloop_done; goto cloop_done;
} }
} }
cloop_done: cloop_done:
; if(err != ASN_OK){
freebytes(ans);
ans = nil;
}
} }
*pp = p; *pp = p;
*pbytes = ans; *pbytes = ans;
@ -736,7 +733,9 @@ seq_decode(uchar** pp, uchar* pend, int length, int isconstr, Elist** pelist)
else else
lve = mkel(elem, lve); lve = mkel(elem, lve);
} }
if(err == ASN_OK) { if(err != ASN_OK)
freeelist(lve);
else {
/* reverse back to original order */ /* reverse back to original order */
while(lve != nil) { while(lve != nil) {
lveold = lve; lveold = lve;
@ -748,7 +747,6 @@ seq_decode(uchar** pp, uchar* pend, int length, int isconstr, Elist** pelist)
} }
*pp = p; *pp = p;
*pelist = ans; *pelist = ans;
setmalloctag(ans, getcallerpc(&pp));
return err; return err;
} }