Skip to content

Commit

Permalink
Fix out-of-bound access in ip6addr_ntoa_r()
Browse files Browse the repository at this point in the history
When detecting that zero is single, code reads the next group even if it is last group.

If next bytes are not-null, last zero is not omitted.

If next bytes are null, last zero is omitted, but since there are no groups left,
finishing ':' will not be written, resulting in invalid address.

This commit turns off non-single zero check for the last group.
  • Loading branch information
sfionov committed Mar 7, 2024
1 parent 0a0452b commit 07ec589
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 11 deletions.
17 changes: 9 additions & 8 deletions src/core/ipv6/ip6_addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,15 +270,16 @@ ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen)

/* Check for empty block. */
if (current_block_value == 0) {
if (current_block_index == 7 && empty_block_flag == 1) {
/* special case, we must render a ':' for the last block. */
buf[i++] = ':';
if (i >= buflen) {
return NULL;
if (current_block_index == 7) {
if (empty_block_flag == 1) {
/* special case, we must render a ':' for the last block. */
buf[i++] = ':';
if (i >= buflen) {
return NULL;
}
break;
}
break;
}
if (empty_block_flag == 0) {
} else if (empty_block_flag == 0) {
/* generate empty block "::", but only if more than one contiguous zero block,
* according to current formatting suggestions RFC 5952. */
next_block_value = lwip_htonl(addr->addr[(current_block_index + 1) >> 1]);
Expand Down
9 changes: 6 additions & 3 deletions test/unit/ip6/test_ip6.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,15 +224,18 @@ END_TEST

struct test_addr_and_str {
ip_addr_t addr;
u32_t bytes_after;
const char *str;
};

START_TEST(test_ip6_ntoa)
{
struct test_addr_and_str tests[] = {
{IPADDR6_INIT_HOST(0xfe800000, 0x00000000, 0xb2a1a2ff, 0xfea3a4a5), "FE80::B2A1:A2FF:FEA3:A4A5"}, /* test shortened zeros */
{IPADDR6_INIT_HOST(0xfe800000, 0xff000000, 0xb2a1a2ff, 0xfea3a4a5), "FE80:0:FF00:0:B2A1:A2FF:FEA3:A4A5"}, /* don't omit single zero blocks */
{IPADDR6_INIT_HOST(0xfe800000, 0xff000000, 0xb2000000, 0x0000a4a5), "FE80:0:FF00:0:B200::A4A5"}, /* omit longest zero block */
{IPADDR6_INIT_HOST(0xfe800000, 0x00000000, 0xb2a1a2ff, 0xfea3a4a5), 0, "FE80::B2A1:A2FF:FEA3:A4A5"}, /* test shortened zeros */
{IPADDR6_INIT_HOST(0xfe800000, 0xff000000, 0xb2a1a2ff, 0xfea3a4a5), 0, "FE80:0:FF00:0:B2A1:A2FF:FEA3:A4A5"}, /* don't omit single zero blocks */
{IPADDR6_INIT_HOST(0xfe800000, 0xff000000, 0xb2000000, 0x0000a4a5), 0, "FE80:0:FF00:0:B200::A4A5"}, /* omit longest zero block */
{IPADDR6_INIT_HOST(0x20010db8, 0x00010002, 0x00030004, 0x00050000), 0, "2001:DB8:1:2:3:4:5:0"}, /* do not omit last zero due to out-of-bounds bug */
{IPADDR6_INIT_HOST(0x20010db8, 0x00010002, 0x00030004, 0x00050000), 1, "2001:DB8:1:2:3:4:5:0"}, /* do not omit last zero due to out-of-bounds bug */
};
char buf[128];
char *str;
Expand Down

0 comments on commit 07ec589

Please sign in to comment.