Potential Buffer Overrun in _asn1_tag_der()
Description of problem:
When merging libtasn1 into grub2, a potential buffer overrun issue was spotted by coverity:
*** CID 435762: Memory - corruptions (OVERRUN)
________________________________________________________________________________________________________
/grub-core/lib/libtasn1/lib/coding.c: 152 in _asn1_tag_der()
146 if (k > ASN1_MAX_TAG_SIZE - 1)
147 break; /* will not encode larger tags */
148 }
149 *ans_len = k + 1;
150 while (k--)
151 ans[*ans_len - 1 - k] = temp[k] + 128;
>>> CID 435762: Memory - corruptions (OVERRUN)
>>> Overrunning array of 4 bytes at byte offset 4 by dereferencing pointer "ans + (*ans_len - 1)".
152 ans[*ans_len - 1] -= 128;
153 }
154 }
155
156 /**
157 * asn1_octet_der:
Here is the code snippet:
k = 0;
while (tag_value != 0)
{
temp[k++] = tag_value & 0x7F;
tag_value >>= 7;
if (k > ASN1_MAX_TAG_SIZE - 1)
break; /* will not encode larger tags */
}
*ans_len = k + 1;
while (k--)
ans[*ans_len - 1 - k] = temp[k] + 128;
In the first while loop, k
may become ASN1_MAX_TAG_SIZE
, i.e.4
, and trigger break
. Then, in the second while loop, the iteration will be like this:
*ans_len - 1 - k: 1, k: 3
*ans_len - 1 - k: 2, k: 2
*ans_len - 1 - k: 3, k: 1
*ans_len - 1 - k: 4, k: 0
The code may access ans[4] which excesses the boundary of the array. Maybe the if statement should be k >= ASN1_MAX_TAG_SIZE - 1
to cap k
below ASN1_MAX_TAG_SIZE
.
The full report is available in grub-devel mailing list:
https://lists.gnu.org/archive/html/grub-devel/2024-02/txtKIuUb5lf3O.txt
Version of libtasn1 used:
4.19
Distributor of libtasn1 (e.g., Ubuntu, Fedora, RHEL)
Upstream official tarball
How reproducible:
Steps to Reproduce:
- one
- two
- three