From d1648631d3c9b712a3b6b662207038c2f29ada1e Mon Sep 17 00:00:00 2001 From: Bill Fenner Date: Tue, 11 Oct 2022 13:16:20 -0700 Subject: [PATCH] OSPF6: Fix an undefined behavior Handle ls_length shorter than sizeof(lsa_hdr) in the same way as OSPF. Use a u_int32 to hold a loop variable initialized with GET_BE_U_4. print-ospf6.c:815:46: runtime error: signed integer overflow: -2147483648 - 1 cannot be represented in type 'int' SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior print-ospf6.c:817:46 [Part of the PR #1012] (cherry picked from commit 7f3c0900e38225fe3a50937c943a7d38bf3f2b22) --- print-ospf6.c | 13 +++++++++++-- tests/TESTLIST | 1 + tests/ospf-signed-integer-ubsan.out | 3 +++ tests/ospf-signed-integer-ubsan.pcap | Bin 0 -> 724 bytes 4 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 tests/ospf-signed-integer-ubsan.out create mode 100644 tests/ospf-signed-integer-ubsan.pcap diff --git a/print-ospf6.c b/print-ospf6.c index 49167954e..b1325364d 100644 --- a/print-ospf6.c +++ b/print-ospf6.c @@ -388,14 +388,23 @@ static int ospf6_print_lshdr(netdissect_options *ndo, const struct lsa6_hdr *lshp, const u_char *dataend) { + u_int ls_length; + if ((const u_char *)(lshp + 1) > dataend) goto trunc; + ls_length = GET_BE_U_2(lshp->ls_length); + if (ls_length < sizeof(struct lsa_hdr)) { + ND_PRINT("\n\t Bogus length %u < header (%zu)", ls_length, + sizeof(struct lsa_hdr)); + goto trunc; + } + ND_PRINT("\n\t Advertising Router %s, seq 0x%08x, age %us, length %zu", GET_IPADDR_STRING(lshp->ls_router), GET_BE_U_4(lshp->ls_seq), GET_BE_U_2(lshp->ls_age), - GET_BE_U_2(lshp->ls_length)-sizeof(struct lsa6_hdr)); + ls_length-sizeof(struct lsa6_hdr)); ospf6_print_ls_type(ndo, GET_BE_U_2(lshp->ls_type), &lshp->ls_stateid); @@ -734,7 +743,7 @@ ospf6_decode_v3(netdissect_options *ndo, const struct lsr6 *lsrp; const struct lsa6_hdr *lshp; const struct lsa6 *lsap; - int i; + uint32_t i; switch (GET_U_1(op->ospf6_type)) { diff --git a/tests/TESTLIST b/tests/TESTLIST index 34c0d7d73..d74405d08 100644 --- a/tests/TESTLIST +++ b/tests/TESTLIST @@ -854,3 +854,4 @@ lwres_with_extra lwres_with_extra.pcap lwres_with_extra.out ip-snmp-leftshift-unsigned ip-snmp-leftshift-unsigned.pcap ip-snmp-leftshift-unsigned.out ip6-snmp-oid-unsigned ip6-snmp-oid-unsigned.pcap ip6-snmp-oid-unsigned.out lwres-pointer-arithmetic-ub lwres-pointer-arithmetic-ub.pcap lwres-pointer-arithmetic-ub.out +ospf-signed-integer-ubsan ospf-signed-integer-ubsan.pcap ospf-signed-integer-ubsan.out -vv diff --git a/tests/ospf-signed-integer-ubsan.out b/tests/ospf-signed-integer-ubsan.out new file mode 100644 index 000000000..b5b0472a1 --- /dev/null +++ b/tests/ospf-signed-integer-ubsan.out @@ -0,0 +1,3 @@ + 1 15:39:26.444985 IP6 (class 0xe0, hlim 1, next-header AH (51) payload length: 532) fe80::1 > fe80::2: AH(length=4(24-bytes),spi=0x00000100,seq=0x1e,icv=0x0a6ab0b271917e05f7a01c58): OSPFv3, LS-Update, length 508 + Router-ID 1.1.1.108, Area 11.234.210.1, Instance 1 + Bogus length 0 < header (20) [|ospf3] diff --git a/tests/ospf-signed-integer-ubsan.pcap b/tests/ospf-signed-integer-ubsan.pcap new file mode 100644 index 0000000000000000000000000000000000000000..11446d9c4fcee346977c0c8679d1dbfaeb8106eb GIT binary patch literal 724 zcmZ9I&nrYx6vxkb@6GefG=y33(#%VmBn!+!l$shVR!U*Xh?=CZn3D7?SR4NUlFUNV ztWbWGovb7_$d8SzX=Y*OI``i9ycwt7kMB93^F8O@yQ|!e0vfo%7yyzu9PF9wz1HDC z0r4;qn;VIz&b9TYIUquhLE#h2f19#b{^LB!d>=PgF- z{@PwL->h`AbjE1tUm)mao7slZlZkc(P2CT0zxu#Rrf*FZZ(UOejFtSg)`92t@mxI*PF4X`baBS2q1v&t|{VLdQ&XR#V4}RPVR(K+1 IiS@g_zcovj_5c6? literal 0 HcmV?d00001