Commit 81fca848 authored by Daniel Salzman's avatar Daniel Salzman

zscanner: improve dname length overflow check

parent cacac425
......@@ -29920,6 +29920,7 @@ tr803:
s->item_length_position = s->dname_tmp_length++;
}
{
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = (*p);
s->item_length++;
......@@ -29931,6 +29932,7 @@ tr803:
goto st256;
tr808:
{
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = (*p);
s->item_length++;
......@@ -29946,6 +29948,7 @@ tr812:
s->item_length_position = s->dname_tmp_length++;
}
{
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = (*p);
s->item_length++;
......@@ -29960,6 +29963,7 @@ tr819:
s->dname_tmp_length++;
}
{
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = (*p);
s->item_length++;
......@@ -29998,6 +30002,8 @@ case 256:
goto tr802;
tr807:
{
// Check for maximum dname length overflow after each label.
// (at least the next label length must follow).
if (s->dname_tmp_length < MAX_DNAME_LENGTH) {
(s->dname)[s->item_length_position] =
(uint8_t)(s->item_length);
......@@ -30007,13 +30013,14 @@ tr807:
}
}
{
memcpy(s->dname + s->dname_tmp_length,
s->zone_origin,
s->zone_origin_length);
// Check for (relative + origin) dname length overflow.
if (s->dname_tmp_length + s->zone_origin_length <= MAX_DNAME_LENGTH) {
memcpy(s->dname + s->dname_tmp_length,
s->zone_origin,
s->zone_origin_length);
s->dname_tmp_length += s->zone_origin_length;
if (s->dname_tmp_length > MAX_DNAME_LENGTH) {
s->dname_tmp_length += s->zone_origin_length;
} else {
WARN(ZS_DNAME_OVERFLOW);
p--; {goto st253;}
}
......@@ -30024,6 +30031,7 @@ tr807:
goto st1088;
tr811:
{
// Enough room for the terminal label is garanteed (_label_exit).
(s->dname)[s->dname_tmp_length++] = 0;
}
{
......@@ -30035,6 +30043,8 @@ tr818:
s->dname_tmp_length++;
}
{
// Check for maximum dname length overflow after each label.
// (at least the next label length must follow).
if (s->dname_tmp_length < MAX_DNAME_LENGTH) {
(s->dname)[s->item_length_position] =
(uint8_t)(s->item_length);
......@@ -30044,13 +30054,14 @@ tr818:
}
}
{
memcpy(s->dname + s->dname_tmp_length,
s->zone_origin,
s->zone_origin_length);
// Check for (relative + origin) dname length overflow.
if (s->dname_tmp_length + s->zone_origin_length <= MAX_DNAME_LENGTH) {
memcpy(s->dname + s->dname_tmp_length,
s->zone_origin,
s->zone_origin_length);
s->dname_tmp_length += s->zone_origin_length;
if (s->dname_tmp_length > MAX_DNAME_LENGTH) {
s->dname_tmp_length += s->zone_origin_length;
} else {
WARN(ZS_DNAME_OVERFLOW);
p--; {goto st253;}
}
......@@ -30061,6 +30072,7 @@ tr818:
goto st1088;
tr822:
{
// Copy already verified zone origin.
memcpy(s->dname,
s->zone_origin,
s->zone_origin_length);
......@@ -30078,6 +30090,8 @@ case 1088:
goto st0;
tr809:
{
// Check for maximum dname length overflow after each label.
// (at least the next label length must follow).
if (s->dname_tmp_length < MAX_DNAME_LENGTH) {
(s->dname)[s->item_length_position] =
(uint8_t)(s->item_length);
......@@ -30092,6 +30106,8 @@ tr820:
s->dname_tmp_length++;
}
{
// Check for maximum dname length overflow after each label.
// (at least the next label length must follow).
if (s->dname_tmp_length < MAX_DNAME_LENGTH) {
(s->dname)[s->item_length_position] =
(uint8_t)(s->item_length);
......@@ -31279,6 +31295,7 @@ case 286:
goto tr882;
tr891:
{
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = (*p);
s->item_length++;
......@@ -31294,6 +31311,7 @@ tr898:
s->item_length_position = s->dname_tmp_length++;
}
{
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = (*p);
s->item_length++;
......@@ -31308,6 +31326,7 @@ tr911:
s->dname_tmp_length++;
}
{
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = (*p);
s->item_length++;
......@@ -31330,6 +31349,7 @@ tr888:
s->item_length_position = s->dname_tmp_length++;
}
{
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = (*p);
s->item_length++;
......@@ -31360,6 +31380,8 @@ case 287:
goto tr882;
tr892:
{
// Check for maximum dname length overflow after each label.
// (at least the next label length must follow).
if (s->dname_tmp_length < MAX_DNAME_LENGTH) {
(s->dname)[s->item_length_position] =
(uint8_t)(s->item_length);
......@@ -31374,6 +31396,8 @@ tr912:
s->dname_tmp_length++;
}
{
// Check for maximum dname length overflow after each label.
// (at least the next label length must follow).
if (s->dname_tmp_length < MAX_DNAME_LENGTH) {
(s->dname)[s->item_length_position] =
(uint8_t)(s->item_length);
......@@ -31442,11 +31466,13 @@ tr904:
goto st289;
tr895:
{
// Enough room for the terminal label is garanteed (_label_exit).
(s->dname)[s->dname_tmp_length++] = 0;
}
goto st289;
tr896:
{
// Enough room for the terminal label is garanteed (_label_exit).
(s->dname)[s->dname_tmp_length++] = 0;
}
{
......@@ -31459,6 +31485,7 @@ tr896:
goto st289;
tr897:
{
// Enough room for the terminal label is garanteed (_label_exit).
(s->dname)[s->dname_tmp_length++] = 0;
}
{
......@@ -31498,6 +31525,7 @@ case 289:
goto tr894;
tr900:
{
// Enough room for the terminal label is garanteed (_label_exit).
(s->dname)[s->dname_tmp_length++] = 0;
}
{
......@@ -31528,6 +31556,7 @@ case 1092:
goto st0;
tr901:
{
// Enough room for the terminal label is garanteed (_label_exit).
(s->dname)[s->dname_tmp_length++] = 0;
}
goto st290;
......@@ -31930,6 +31959,7 @@ case 300:
goto tr928;
tr939:
{
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = (*p);
s->item_length++;
......@@ -31945,6 +31975,7 @@ tr945:
s->item_length_position = s->dname_tmp_length++;
}
{
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = (*p);
s->item_length++;
......@@ -31959,6 +31990,7 @@ tr956:
s->dname_tmp_length++;
}
{
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = (*p);
s->item_length++;
......@@ -31981,6 +32013,7 @@ tr932:
s->item_length_position = s->dname_tmp_length++;
}
{
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = (*p);
s->item_length++;
......@@ -32011,6 +32044,8 @@ case 301:
goto tr938;
tr940:
{
// Check for maximum dname length overflow after each label.
// (at least the next label length must follow).
if (s->dname_tmp_length < MAX_DNAME_LENGTH) {
(s->dname)[s->item_length_position] =
(uint8_t)(s->item_length);
......@@ -32025,6 +32060,8 @@ tr957:
s->dname_tmp_length++;
}
{
// Check for maximum dname length overflow after each label.
// (at least the next label length must follow).
if (s->dname_tmp_length < MAX_DNAME_LENGTH) {
(s->dname)[s->item_length_position] =
(uint8_t)(s->item_length);
......@@ -32093,6 +32130,7 @@ tr951:
goto st303;
tr942:
{
// Enough room for the terminal label is garanteed (_label_exit).
(s->dname)[s->dname_tmp_length++] = 0;
}
{
......@@ -32101,6 +32139,7 @@ tr942:
goto st303;
tr943:
{
// Enough room for the terminal label is garanteed (_label_exit).
(s->dname)[s->dname_tmp_length++] = 0;
}
{
......@@ -32116,6 +32155,7 @@ tr943:
goto st303;
tr944:
{
// Enough room for the terminal label is garanteed (_label_exit).
(s->dname)[s->dname_tmp_length++] = 0;
}
{
......@@ -32289,6 +32329,7 @@ tr935:
goto st1093;
tr947:
{
// Enough room for the terminal label is garanteed (_label_exit).
(s->dname)[s->dname_tmp_length++] = 0;
}
{
......@@ -32375,6 +32416,7 @@ tr926:
goto st304;
tr948:
{
// Enough room for the terminal label is garanteed (_label_exit).
(s->dname)[s->dname_tmp_length++] = 0;
}
{
......@@ -5349,6 +5349,7 @@ _match:
break;
case 10:
{
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = (*p);
s->item_length++;
......@@ -5360,6 +5361,8 @@ _match:
break;
case 11:
{
// Check for maximum dname length overflow after each label.
// (at least the next label length must follow).
if (s->dname_tmp_length < MAX_DNAME_LENGTH) {
(s->dname)[s->item_length_position] =
(uint8_t)(s->item_length);
......@@ -5399,18 +5402,20 @@ _match:
break;
case 16:
{
// Enough room for the terminal label is garanteed (_label_exit).
(s->dname)[s->dname_tmp_length++] = 0;
}
break;
case 17:
{
memcpy(s->dname + s->dname_tmp_length,
s->zone_origin,
s->zone_origin_length);
// Check for (relative + origin) dname length overflow.
if (s->dname_tmp_length + s->zone_origin_length <= MAX_DNAME_LENGTH) {
memcpy(s->dname + s->dname_tmp_length,
s->zone_origin,
s->zone_origin_length);
s->dname_tmp_length += s->zone_origin_length;
if (s->dname_tmp_length > MAX_DNAME_LENGTH) {
s->dname_tmp_length += s->zone_origin_length;
} else {
WARN(ZS_DNAME_OVERFLOW);
p--; {cs = 253; goto _again;}
}
......@@ -5418,6 +5423,7 @@ _match:
break;
case 18:
{
// Copy already verified zone origin.
memcpy(s->dname,
s->zone_origin,
s->zone_origin_length);
......
......@@ -123,10 +123,10 @@ struct scanner {
uint32_t item_length_position;
/*! Auxiliary pointer to item length. */
uint8_t *item_length_location;
/*! Auxiliary buffer for data storing. */
uint8_t buffer[MAX_RDATA_LENGTH];
/*! Auxiliary buffer length. */
uint32_t buffer_length;
/*! Auxiliary buffer for data storing. */
uint8_t buffer[MAX_RDATA_LENGTH];
/*! Auxiliary buffer for current included file name. */
char include_filename[MAX_RDATA_LENGTH + 1];
......@@ -151,10 +151,14 @@ struct scanner {
/*! Position of the last free r_data byte. */
uint32_t r_data_tail;
/*! Wire format of the current origin (ORIGIN directive sets this). */
uint8_t zone_origin[MAX_DNAME_LENGTH];
/*! Length of the current origin. */
uint32_t zone_origin_length;
/*!
* Wire format of the current origin (ORIGIN directive sets this).
*
* \note Maximal dname length check is after each valid label.
*/
uint8_t zone_origin[MAX_DNAME_LENGTH + MAX_LABEL_LENGTH];
/*! Value of the default class. */
uint16_t default_class;
/*! Value of the current default ttl (TTL directive sets this). */
......@@ -188,36 +192,35 @@ struct scanner {
int descriptor;
} file;
/*! Length of the current record owner. */
uint32_t r_owner_length;
/*!
* Owner of the current record.
*
* \note The double length of the r_owner is due to dname length
* check is after concatenation of relative and origin dnames.
* \note Maximal dname length check is after each valid label.
*/
uint8_t r_owner[2 * MAX_DNAME_LENGTH];
/*! Length of the current record owner. */
uint32_t r_owner_length;
uint8_t r_owner[MAX_DNAME_LENGTH + MAX_LABEL_LENGTH];
/*! Class of the current record. */
uint16_t r_class;
/*! TTL of the current record. */
uint32_t r_ttl;
/*! Type of the current record data. */
uint16_t r_type;
/*! Current rdata. */
uint8_t r_data[MAX_RDATA_LENGTH];
/*! Length of the current rdata. */
uint32_t r_data_length;
/*! Current rdata. */
uint8_t r_data[MAX_RDATA_LENGTH];
/*
* Example: a. IN 60 MX 1 b.
*
* r_owner = 016100
* r_owner_length = 3
* r_owner = 016100
* r_class = 1
* r_ttl = 60
* r_type = 15
* r_data = 0001016200
* r_data_length = 5
* r_data = 0001016200
*/
};
......
......@@ -110,6 +110,7 @@
s->item_length_position = s->dname_tmp_length++;
}
action _label_char {
// Check for maximum dname label length.
if (s->item_length < MAX_LABEL_LENGTH) {
(s->dname)[s->dname_tmp_length++] = fc;
s->item_length++;
......@@ -119,6 +120,8 @@
}
}
action _label_exit {
// Check for maximum dname length overflow after each label.
// (at least the next label length must follow).
if (s->dname_tmp_length < MAX_DNAME_LENGTH) {
(s->dname)[s->item_length_position] =
(uint8_t)(s->item_length);
......@@ -164,21 +167,24 @@
# BEGIN - Domain name processing.
action _absolute_dname_exit {
// Enough room for the terminal label is garanteed (_label_exit).
(s->dname)[s->dname_tmp_length++] = 0;
}
action _relative_dname_exit {
memcpy(s->dname + s->dname_tmp_length,
s->zone_origin,
s->zone_origin_length);
// Check for (relative + origin) dname length overflow.
if (s->dname_tmp_length + s->zone_origin_length <= MAX_DNAME_LENGTH) {
memcpy(s->dname + s->dname_tmp_length,
s->zone_origin,
s->zone_origin_length);
s->dname_tmp_length += s->zone_origin_length;
if (s->dname_tmp_length > MAX_DNAME_LENGTH) {
s->dname_tmp_length += s->zone_origin_length;
} else {
WARN(ZS_DNAME_OVERFLOW);
fhold; fgoto err_line;
}
}
action _origin_dname_exit {
// Copy already verified zone origin.
memcpy(s->dname,
s->zone_origin,
s->zone_origin_length);
......
......@@ -33,3 +33,5 @@ b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. NS @ ;
12345678901234567890123456789012345678901234567890123456789012\0514.tld. NS @ ; Label exceeded maximal length
123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012. NS @ ; Domain name exceeded maximal length
123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012 NS @ ; Domain name exceeded maximal length (after appending origin)
123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.1 NS @ ; Domain name exceeded maximal length (maximal dname length check is after each valid label)
123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.123456789012345678901234567890123456789012345678901234567890123 NS @ ; Domain name exceeded maximal length (maximal dname length check is after each valid label)
......@@ -132,3 +132,7 @@ WARNG=ZS_DNAME_OVERFLOW
------
WARNG=ZS_DNAME_OVERFLOW
------
WARNG=ZS_DNAME_OVERFLOW
------
WARNG=ZS_DNAME_OVERFLOW
------
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment