summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authortb <>2022-01-04 20:17:07 +0000
committertb <>2022-01-04 20:17:07 +0000
commit6da8a2384aedc4bf32ae2540bf15c32ff1f208fe (patch)
tree41e77008e192a5ddf738116c0af4c65c872f0282 /src/lib
parenta25565ae3b2b126c8949d6f47ebc3b98a26e4c7c (diff)
downloadopenbsd-6da8a2384aedc4bf32ae2540bf15c32ff1f208fe.tar.gz
openbsd-6da8a2384aedc4bf32ae2540bf15c32ff1f208fe.tar.bz2
openbsd-6da8a2384aedc4bf32ae2540bf15c32ff1f208fe.zip
Add a length check to make_addressPrefix()
Make the callers pass in the afi so that make_addressPrefix() can check prefixlen to be reasonable. If the afi is anything else than IPv4 or IPv6, cap its length at the length needed for IPv6. This way we avoid arbitrary out-of-bounds reads if the caller decides to pass in something stupid. ok inoguchi jsing
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/x509/x509_addr.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/src/lib/libcrypto/x509/x509_addr.c b/src/lib/libcrypto/x509/x509_addr.c
index a3d5ec74ec..fdb2f64fd2 100644
--- a/src/lib/libcrypto/x509/x509_addr.c
+++ b/src/lib/libcrypto/x509/x509_addr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_addr.c,v 1.51 2022/01/04 20:04:38 tb Exp $ */ 1/* $OpenBSD: x509_addr.c,v 1.52 2022/01/04 20:17:07 tb Exp $ */
2/* 2/*
3 * Contributed to the OpenSSL Project by the American Registry for 3 * Contributed to the OpenSSL Project by the American Registry for
4 * Internet Numbers ("ARIN"). 4 * Internet Numbers ("ARIN").
@@ -802,18 +802,32 @@ range_should_be_prefix(const unsigned char *min, const unsigned char *max,
802 */ 802 */
803static int 803static int
804make_addressPrefix(IPAddressOrRange **result, unsigned char *addr, 804make_addressPrefix(IPAddressOrRange **result, unsigned char *addr,
805 const int prefixlen) 805 unsigned int afi, int prefixlen)
806{ 806{
807 int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; 807 IPAddressOrRange *aor;
808 IPAddressOrRange *aor = IPAddressOrRange_new(); 808 int afi_length, bytelen, bitlen, max_length;
809
810 if (prefixlen < 0)
811 return 0;
812
813 max_length = 16;
814 if ((afi_length = length_from_afi(afi)) > 0)
815 max_length = afi_length;
816 if (prefixlen > 8 * max_length)
817 return 0;
809 818
810 if (aor == NULL) 819 bytelen = (prefixlen + 7) / 8;
820 bitlen = prefixlen % 8;
821
822 if ((aor = IPAddressOrRange_new()) == NULL)
811 return 0; 823 return 0;
812 aor->type = IPAddressOrRange_addressPrefix; 824 aor->type = IPAddressOrRange_addressPrefix;
813 if ((aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) 825 if ((aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL)
814 goto err; 826 goto err;
827
815 if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen)) 828 if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen))
816 goto err; 829 goto err;
830
817 aor->u.addressPrefix->flags &= ~7; 831 aor->u.addressPrefix->flags &= ~7;
818 aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT; 832 aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT;
819 if (bitlen > 0) { 833 if (bitlen > 0) {
@@ -836,13 +850,13 @@ make_addressPrefix(IPAddressOrRange **result, unsigned char *addr,
836 */ 850 */
837static int 851static int
838make_addressRange(IPAddressOrRange **result, unsigned char *min, 852make_addressRange(IPAddressOrRange **result, unsigned char *min,
839 unsigned char *max, const int length) 853 unsigned char *max, unsigned int afi, int length)
840{ 854{
841 IPAddressOrRange *aor; 855 IPAddressOrRange *aor;
842 int i, prefixlen; 856 int i, prefixlen;
843 857
844 if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0) 858 if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
845 return make_addressPrefix(result, min, prefixlen); 859 return make_addressPrefix(result, min, afi, prefixlen);
846 860
847 if ((aor = IPAddressOrRange_new()) == NULL) 861 if ((aor = IPAddressOrRange_new()) == NULL)
848 return 0; 862 return 0;
@@ -1005,12 +1019,10 @@ X509v3_addr_add_prefix(IPAddrBlocks *addr, const unsigned afi,
1005 IPAddressOrRanges *aors; 1019 IPAddressOrRanges *aors;
1006 IPAddressOrRange *aor; 1020 IPAddressOrRange *aor;
1007 1021
1008 /* XXX - check prefixlen */
1009
1010 if ((aors = make_prefix_or_range(addr, afi, safi)) == NULL) 1022 if ((aors = make_prefix_or_range(addr, afi, safi)) == NULL)
1011 return 0; 1023 return 0;
1012 1024
1013 if (!make_addressPrefix(&aor, a, prefixlen)) 1025 if (!make_addressPrefix(&aor, a, afi, prefixlen))
1014 return 0; 1026 return 0;
1015 1027
1016 if (sk_IPAddressOrRange_push(aors, aor) <= 0) { 1028 if (sk_IPAddressOrRange_push(aors, aor) <= 0) {
@@ -1037,7 +1049,7 @@ X509v3_addr_add_range(IPAddrBlocks *addr, const unsigned afi,
1037 1049
1038 length = length_from_afi(afi); 1050 length = length_from_afi(afi);
1039 1051
1040 if (!make_addressRange(&aor, min, max, length)) 1052 if (!make_addressRange(&aor, min, max, afi, length))
1041 return 0; 1053 return 0;
1042 1054
1043 if (sk_IPAddressOrRange_push(aors, aor) <= 0) { 1055 if (sk_IPAddressOrRange_push(aors, aor) <= 0) {
@@ -1284,7 +1296,8 @@ IPAddressOrRanges_canonize(IPAddressOrRanges *aors, const unsigned afi)
1284 continue; 1296 continue;
1285 if (memcmp(a_max, b_min, length) == 0) { 1297 if (memcmp(a_max, b_min, length) == 0) {
1286 IPAddressOrRange *merged; 1298 IPAddressOrRange *merged;
1287 if (!make_addressRange(&merged, a_min, b_max, length)) 1299 if (!make_addressRange(&merged, a_min, b_max, afi,
1300 length))
1288 return 0; 1301 return 0;
1289 (void)sk_IPAddressOrRange_set(aors, i, merged); 1302 (void)sk_IPAddressOrRange_set(aors, i, merged);
1290 (void)sk_IPAddressOrRange_delete(aors, i + 1); 1303 (void)sk_IPAddressOrRange_delete(aors, i + 1);