Mercurial > hg > freeDiameter
comparison libfdproto/messages.c @ 920:cb439d57d0c5
Fix parsing of incoming AVPs with 0-byte length at the end of the message
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Tue, 12 Feb 2013 18:42:33 +0100 |
parents | b1776283d69e |
children | 877592751fee |
comparison
equal
deleted
inserted
replaced
919:b1776283d69e | 920:cb439d57d0c5 |
---|---|
1650 TRACE_ENTRY("%p %d %p", buf, buflen, head); | 1650 TRACE_ENTRY("%p %d %p", buf, buflen, head); |
1651 | 1651 |
1652 while (offset < buflen) { | 1652 while (offset < buflen) { |
1653 struct avp * avp; | 1653 struct avp * avp; |
1654 | 1654 |
1655 if (buflen - offset <= AVPHDRSZ_NOVEND) { | 1655 if (buflen - offset < AVPHDRSZ_NOVEND) { |
1656 TRACE_DEBUG(INFO, "truncated buffer: remaining only %d bytes", buflen - offset); | 1656 TRACE_DEBUG(INFO, "truncated buffer: remaining only %d bytes", buflen - offset); |
1657 return EBADMSG; | 1657 return EBADMSG; |
1658 } | 1658 } |
1659 | 1659 |
1660 /* Create a new AVP object */ | 1660 /* Create a new AVP object */ |
1668 avp->avp_public.avp_len = ((uint32_t)buf[offset+5]) << 16 | ((uint32_t)buf[offset+6]) << 8 | ((uint32_t)buf[offset+7]) ; | 1668 avp->avp_public.avp_len = ((uint32_t)buf[offset+5]) << 16 | ((uint32_t)buf[offset+6]) << 8 | ((uint32_t)buf[offset+7]) ; |
1669 | 1669 |
1670 offset += 8; | 1670 offset += 8; |
1671 | 1671 |
1672 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { | 1672 if (avp->avp_public.avp_flags & AVP_FLAG_VENDOR) { |
1673 if (buflen - offset <= 4) { | 1673 if (buflen - offset < 4) { |
1674 TRACE_DEBUG(INFO, "truncated buffer: remaining only %d bytes for vendor and data", buflen - offset); | 1674 TRACE_DEBUG(INFO, "truncated buffer: remaining only %d bytes for vendor and data", buflen - offset); |
1675 free(avp); | 1675 free(avp); |
1676 return EBADMSG; | 1676 return EBADMSG; |
1677 } | 1677 } |
1678 avp->avp_public.avp_vendor = ntohl(*(uint32_t *)(buf + offset)); | 1678 avp->avp_public.avp_vendor = ntohl(*(uint32_t *)(buf + offset)); |
1679 offset += 4; | 1679 offset += 4; |
1680 } | 1680 } |
1681 | 1681 |
1682 /* Check there is enough remaining data in the buffer */ | 1682 /* Check there is enough remaining data in the buffer */ |
1683 if (buflen - offset < avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags)) { | 1683 if ( (avp->avp_public.avp_len > GETAVPHDRSZ(avp->avp_public.avp_flags)) |
1684 && (buflen - offset < avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags))) { | |
1684 TRACE_DEBUG(INFO, "truncated buffer: remaining only %d bytes for data, and avp data size is %d", | 1685 TRACE_DEBUG(INFO, "truncated buffer: remaining only %d bytes for data, and avp data size is %d", |
1685 buflen - offset, | 1686 buflen - offset, |
1686 avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags)); | 1687 avp->avp_public.avp_len - GETAVPHDRSZ(avp->avp_public.avp_flags)); |
1687 free(avp); | 1688 free(avp); |
1688 return EBADMSG; | 1689 return EBADMSG; |