mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-28 21:07:43 +00:00
[master] Correct buffer overrun in pretty_print_option
Merges in rt47139.
This commit is contained in:
parent
197b26f253
commit
c5931725b4
8
RELNOTES
8
RELNOTES
@ -101,7 +101,13 @@ by Eric Young (eay@cryptsoft.com).
|
|||||||
when parsing buffer for options. Reported by Felix Wilhelm, Google
|
when parsing buffer for options. Reported by Felix Wilhelm, Google
|
||||||
Security Team.
|
Security Team.
|
||||||
[ISC-Bugs #47140]
|
[ISC-Bugs #47140]
|
||||||
CVE: CVE-2018-xxxx
|
CVE: CVE-2018-5733
|
||||||
|
|
||||||
|
! Corrected an issue where large sized 'X/x' format options were causing
|
||||||
|
option handling logic to overwrite memory when expanding them to human
|
||||||
|
readable form. Reported by Felix Wilhelm, Google Security Team.
|
||||||
|
[ISC-Bugs #47139]
|
||||||
|
CVE: CVE-2018-5732
|
||||||
|
|
||||||
Changes since 4.4.0b1 (New Features)
|
Changes since 4.4.0b1 (New Features)
|
||||||
|
|
||||||
|
@ -1776,7 +1776,8 @@ format_min_length(format, oc)
|
|||||||
|
|
||||||
|
|
||||||
/* Format the specified option so that a human can easily read it. */
|
/* Format the specified option so that a human can easily read it. */
|
||||||
|
/* Maximum pretty printed size */
|
||||||
|
#define MAX_OUTPUT_SIZE 32*1024
|
||||||
const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
||||||
struct option *option;
|
struct option *option;
|
||||||
const unsigned char *data;
|
const unsigned char *data;
|
||||||
@ -1784,8 +1785,9 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
|||||||
int emit_commas;
|
int emit_commas;
|
||||||
int emit_quotes;
|
int emit_quotes;
|
||||||
{
|
{
|
||||||
static char optbuf [32768]; /* XXX */
|
/* We add 128 byte pad so we don't have to add checks everywhere. */
|
||||||
static char *endbuf = &optbuf[sizeof(optbuf)];
|
static char optbuf [MAX_OUTPUT_SIZE + 128]; /* XXX */
|
||||||
|
static char *endbuf = optbuf + MAX_OUTPUT_SIZE;
|
||||||
int hunksize = 0;
|
int hunksize = 0;
|
||||||
int opthunk = 0;
|
int opthunk = 0;
|
||||||
int hunkinc = 0;
|
int hunkinc = 0;
|
||||||
@ -2211,7 +2213,14 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
|
|||||||
log_error ("Unexpected format code %c",
|
log_error ("Unexpected format code %c",
|
||||||
fmtbuf [j]);
|
fmtbuf [j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
op += strlen (op);
|
op += strlen (op);
|
||||||
|
if (op >= endbuf) {
|
||||||
|
log_error ("Option data exceeds"
|
||||||
|
" maximum size %d", MAX_OUTPUT_SIZE);
|
||||||
|
return ("<error>");
|
||||||
|
}
|
||||||
|
|
||||||
if (dp == data + len)
|
if (dp == data + len)
|
||||||
break;
|
break;
|
||||||
if (j + 1 < numelem && comma != ':')
|
if (j + 1 < numelem && comma != ':')
|
||||||
|
@ -68,12 +68,75 @@ ATF_TC_BODY(option_refcnt, tc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ATF_TC(pretty_print_option);
|
||||||
|
|
||||||
|
ATF_TC_HEAD(pretty_print_option, tc)
|
||||||
|
{
|
||||||
|
atf_tc_set_md_var(tc, "descr",
|
||||||
|
"Verify pretty_print_option does not overrun its buffer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This test verifies that pretty_print_option() will not overrun its
|
||||||
|
* internal, static buffer when given large 'x/X' format options.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ATF_TC_BODY(pretty_print_option, tc)
|
||||||
|
{
|
||||||
|
struct option *option;
|
||||||
|
unsigned code;
|
||||||
|
unsigned char bad_data[32*1024];
|
||||||
|
unsigned char good_data[] = { 1,2,3,4,5,6 };
|
||||||
|
int emit_commas = 1;
|
||||||
|
int emit_quotes = 1;
|
||||||
|
const char *output_buf;
|
||||||
|
|
||||||
|
/* Initialize whole thing to non-printable chars */
|
||||||
|
memset(bad_data, 0x1f, sizeof(bad_data));
|
||||||
|
|
||||||
|
initialize_common_option_spaces();
|
||||||
|
|
||||||
|
/* We'll use dhcp_client_identitifer because it happens to be format X */
|
||||||
|
code = 61;
|
||||||
|
option = NULL;
|
||||||
|
if (!option_code_hash_lookup(&option, dhcp_universe.code_hash,
|
||||||
|
&code, 0, MDL)) {
|
||||||
|
atf_tc_fail("can't find option %d", code);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option == NULL) {
|
||||||
|
atf_tc_fail("option is NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First we will try a good value we know should fit. */
|
||||||
|
output_buf = pretty_print_option (option, good_data, sizeof(good_data),
|
||||||
|
emit_commas, emit_quotes);
|
||||||
|
|
||||||
|
/* Make sure we get what we expect */
|
||||||
|
if (!output_buf || strcmp(output_buf, "1:2:3:4:5:6")) {
|
||||||
|
atf_tc_fail("pretty_print_option did not return \"<error>\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Now we'll try a data value that's too large */
|
||||||
|
output_buf = pretty_print_option (option, bad_data, sizeof(bad_data),
|
||||||
|
emit_commas, emit_quotes);
|
||||||
|
|
||||||
|
/* Make sure we safely get an error */
|
||||||
|
if (!output_buf || strcmp(output_buf, "<error>")) {
|
||||||
|
atf_tc_fail("pretty_print_option did not return \"<error>\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This macro defines main() method that will call specified
|
/* This macro defines main() method that will call specified
|
||||||
test cases. tp and simple_test_case names can be whatever you want
|
test cases. tp and simple_test_case names can be whatever you want
|
||||||
as long as it is a valid variable identifier. */
|
as long as it is a valid variable identifier. */
|
||||||
ATF_TP_ADD_TCS(tp)
|
ATF_TP_ADD_TCS(tp)
|
||||||
{
|
{
|
||||||
ATF_TP_ADD_TC(tp, option_refcnt);
|
ATF_TP_ADD_TC(tp, option_refcnt);
|
||||||
|
ATF_TP_ADD_TC(tp, pretty_print_option);
|
||||||
|
|
||||||
return (atf_no_error());
|
return (atf_no_error());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user