Skip to content

Commit

Permalink
bgpd: fix heap buffer overflow in lcom -> str enc
Browse files Browse the repository at this point in the history
Spaces were not being accounted for in the heap buffer sizing, leading
to a heap buffer overflow when encoding large communities to their
string representations.

This patch also uses safer functions to do the encoding instead of
pointer math.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
  • Loading branch information
qlyoung authored and Santosh P K committed Dec 20, 2019
1 parent 68dc0c9 commit a45bd08
Showing 1 changed file with 17 additions and 19 deletions.
36 changes: 17 additions & 19 deletions bgpd/bgp_lcommunity.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,14 @@ static void set_lcommunity_string(struct lcommunity *lcom, bool make_json)
{
int i;
int len;
bool first = true;
char *str_buf;
char *str_pnt;
uint8_t *pnt;
uint32_t global, local1, local2;
json_object *json_lcommunity_list = NULL;
json_object *json_string = NULL;

#define LCOMMUNITY_STR_DEFAULT_LEN 32
/* 3 32-bit integers, 2 colons, and a space */
#define LCOMMUNITY_STRLEN (10 * 3 + 2 + 1)

if (!lcom)
return;
Expand All @@ -196,8 +195,7 @@ static void set_lcommunity_string(struct lcommunity *lcom, bool make_json)
}

if (lcom->size == 0) {
str_buf = XMALLOC(MTYPE_LCOMMUNITY_STR, 1);
str_buf[0] = '\0';
str_buf = XCALLOC(MTYPE_LCOMMUNITY_STR, 1);

if (make_json) {
json_object_string_add(lcom->json, "string", "");
Expand All @@ -209,35 +207,35 @@ static void set_lcommunity_string(struct lcommunity *lcom, bool make_json)
return;
}

str_buf = str_pnt =
XMALLOC(MTYPE_LCOMMUNITY_STR,
(LCOMMUNITY_STR_DEFAULT_LEN * lcom->size) + 1);
/* 1 space + lcom->size lcom strings + null terminator */
size_t str_buf_sz = (LCOMMUNITY_STRLEN * lcom->size) + 2;
str_buf = XCALLOC(MTYPE_LCOMMUNITY_STR, str_buf_sz);

for (i = 0; i < lcom->size; i++) {
if (first)
first = false;
else
*str_pnt++ = ' ';
if (i > 0)
strlcat(str_buf, " ", str_buf_sz);

pnt = lcom->val + (i * LCOMMUNITY_SIZE);
pnt = ptr_get_be32(pnt, &global);
pnt = ptr_get_be32(pnt, &local1);
pnt = ptr_get_be32(pnt, &local2);
(void)pnt;

len = sprintf(str_pnt, "%u:%u:%u", global, local1, local2);
char lcsb[LCOMMUNITY_STRLEN + 1];

snprintf(lcsb, sizeof(lcsb), "%u:%u:%u", global, local1,
local2);

len = strlcat(str_buf, lcsb, str_buf_sz);
assert((unsigned int)len < str_buf_sz);

if (make_json) {
json_string = json_object_new_string(str_pnt);
json_string = json_object_new_string(lcsb);
json_object_array_add(json_lcommunity_list,
json_string);
}

str_pnt += len;
}

str_buf =
XREALLOC(MTYPE_LCOMMUNITY_STR, str_buf, str_pnt - str_buf + 1);

if (make_json) {
json_object_string_add(lcom->json, "string", str_buf);
json_object_object_add(lcom->json, "list",
Expand Down

0 comments on commit a45bd08

Please sign in to comment.