Fix user-defined format stack-smash ability.

'-F' option: Avoids risk of stack-smashing which was ever so present,
by just fprintf'ing directly to output stream.
This commit is contained in:
Chris Caputo
2020-03-09 01:01:16 +00:00
parent b71aa3f21d
commit e4d72f0505
3 changed files with 32 additions and 30 deletions

View File

@@ -1633,7 +1633,6 @@ struct fpcbdata {
void
bgpq4_print_format_prefix(struct sx_radix_node* n, void* ff)
{
char prefix[128];
struct fpcbdata* fpc = (struct fpcbdata*)ff;
FILE* f = fpc->f;
struct bgpq_expander* b = fpc->b;
@@ -1644,13 +1643,9 @@ bgpq4_print_format_prefix(struct sx_radix_node* n, void* ff)
if (!f)
f = stdout;
memset(prefix, 0, sizeof(prefix));
sx_prefix_snprintf_fmt(n->prefix, prefix, sizeof(prefix),
sx_prefix_snprintf_fmt(n->prefix, f,
b->name ? b->name : "NN",
b->format);
fprintf(f, "%s", prefix);
}

View File

@@ -399,74 +399,81 @@ sx_prefix_snprintf(struct sx_prefix* p, char* rbuffer, int srb)
return sx_prefix_snprintf_sep(p, rbuffer, srb, "/");
}
int
sx_prefix_snprintf_fmt(struct sx_prefix* p, char* buffer, int size,
void
sx_prefix_snprintf_fmt(struct sx_prefix* p, FILE* f,
const char* name, const char* format)
{
unsigned off = 0;
const char* c = format;
struct sx_prefix *q = sx_prefix_alloc(NULL);
char prefix[128];
while (*c) {
if(*c == '%') {
switch (*(c + 1)) {
case 'r':
case 'n':
inet_ntop(p->family, &p->addr, buffer+off, size-off);
off = strlen(buffer);
if (NULL != inet_ntop(p->family, &p->addr, prefix, sizeof(prefix))) {
fprintf(f, "%s", prefix);
} else {
sx_report(SX_ERROR, "inet_ntop failed\n");
return;
}
break;
case 'l':
off += snprintf(buffer + off, size - off,
"%i", p->masklen);
fprintf(f, "%i", p->masklen);
break;
case '%':
buffer[off++] = '%';
fprintf(f, "%%");
break;
case 'N':
off += snprintf(buffer + off, size - off,
"%s", name);
fprintf(f, "%s", name);
break;
case 'm':
sx_prefix_mask(p, q);
inet_ntop(p->family, &q->addr, buffer + off,
size - off);
off = strlen(buffer);
if (NULL != inet_ntop(p->family, &q->addr, prefix, sizeof(prefix))) {
fprintf(f, "%s", prefix);
} else {
sx_report(SX_ERROR, "inet_ntop failed\n");
return;
}
break;
case 'i':
sx_prefix_imask(p, q);
inet_ntop(p->family, &q->addr, buffer + off,
size - off);
off = strlen(buffer);
if (NULL != inet_ntop(p->family, &q->addr, prefix, sizeof(prefix))) {
fprintf(f, "%s", prefix);
} else {
sx_report(SX_ERROR, "inet_ntop failed\n");
return;
}
break;
default :
sx_report(SX_ERROR, "Unknown format char "
"'%c'\n", *(c + 1));
return 0;
return;
}
c += 2;
} else if (*c == '\\') {
switch(*(c+1)) {
case 'n':
buffer[off++] = '\n';
fprintf(f, "\n");
break;
case 't':
buffer[off++] = '\t';
fprintf(f, "\t");
break;
case '\\':
buffer[off++] = '\\';
fprintf(f, "\\");
break;
default:
buffer[off++] = *(c + 1);
fprintf(f, "%c", *(c + 1));
break;
}
c += 2;
} else {
buffer[off++] = *c;
fprintf(f, "%c", *c);
c++;
}
}
return strlen(buffer);
}
int

View File

@@ -51,7 +51,7 @@ int sx_prefix_range_parse(struct sx_radix_tree* t, int af, int ml, char* text);
int sx_prefix_fprint(FILE* f, struct sx_prefix* p);
int sx_prefix_snprintf(struct sx_prefix* p, char* rbuffer, int srb);
int sx_prefix_snprintf_sep(struct sx_prefix* p, char* rbuffer, int srb, char*);
int sx_prefix_snprintf_fmt(struct sx_prefix* p, char* rbuffer, int srb,
void sx_prefix_snprintf_fmt(struct sx_prefix* p, FILE* f,
const char* name, const char* fmt);
int sx_prefix_jsnprintf(struct sx_prefix* p, char* rbuffer, int srb);
struct sx_radix_tree* sx_radix_tree_new(int af);