Skip to content

Commit f6d684a

Browse files
committed
parser BUGFIX long identity name buffer overflow
STRING_OVERFLOW (CWE-120)
1 parent 9c3ee62 commit f6d684a

File tree

1 file changed

+57
-23
lines changed

1 file changed

+57
-23
lines changed

src/parser.c

Lines changed: 57 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ lyp_precompile_pattern(struct ly_ctx *ctx, const char *pattern, pcre** pcre_cmp,
979979
* @param[in] data2 If \p type is #LY_TYPE_BITS: (int *) type bit field length,
980980
* #LY_TYPE_DEC64: (uint8_t *) number of fraction digits (position of the floating point),
981981
* otherwise ignored.
982-
* @return 1 if a conversion took place, 0 if the value was kept the same.
982+
* @return 1 if a conversion took place, 0 if the value was kept the same, -1 on error.
983983
*/
984984
static int
985985
make_canonical(struct ly_ctx *ctx, int type, const char **value, void *data1, void *data2)
@@ -994,6 +994,8 @@ make_canonical(struct ly_ctx *ctx, int type, const char **value, void *data1, vo
994994
uint64_t unum;
995995
uint8_t c;
996996

997+
#define LOGBUF(str) LOGERR(ctx, LY_EINVAL, "Value \"%s\" is too long.", str)
998+
997999
switch (type) {
9981000
case LY_TYPE_BITS:
9991001
bits = (struct lys_type_bit **)data1;
@@ -1006,8 +1008,10 @@ make_canonical(struct ly_ctx *ctx, int type, const char **value, void *data1, vo
10061008
continue;
10071009
}
10081010
if (buf[0]) {
1011+
LY_CHECK_ERR_RETURN(strlen(buf) + 1 + strlen(bits[i]->name) > buf_len, LOGBUF(bits[i]->name), -1);
10091012
sprintf(buf + strlen(buf), " %s", bits[i]->name);
10101013
} else {
1014+
LY_CHECK_ERR_RETURN(strlen(bits[i]->name) > buf_len, LOGBUF(bits[i]->name), -1);
10111015
strcpy(buf, bits[i]->name);
10121016
}
10131017
}
@@ -1025,7 +1029,7 @@ make_canonical(struct ly_ctx *ctx, int type, const char **value, void *data1, vo
10251029

10261030
case LY_TYPE_INST:
10271031
exp = lyxp_parse_expr(ctx, *value);
1028-
LY_CHECK_ERR_RETURN(!exp, LOGINT(ctx), 0);
1032+
LY_CHECK_ERR_RETURN(!exp, LOGINT(ctx), -1);
10291033

10301034
module_name = NULL;
10311035
count = 0;
@@ -1035,9 +1039,9 @@ make_canonical(struct ly_ctx *ctx, int type, const char **value, void *data1, vo
10351039
/* copy WS */
10361040
if (i && ((end = exp->expr + exp->expr_pos[i - 1] + exp->tok_len[i - 1]) != cur_expr)) {
10371041
if (count + (cur_expr - end) > buf_len) {
1038-
LOGINT(ctx);
10391042
lyxp_expr_free(exp);
1040-
return 0;
1043+
LOGBUF(end);
1044+
return -1;
10411045
}
10421046
strncpy(&buf[count], end, cur_expr - end);
10431047
count += cur_expr - end;
@@ -1051,9 +1055,9 @@ make_canonical(struct ly_ctx *ctx, int type, const char **value, void *data1, vo
10511055
if (!module_name || strncmp(cur_expr, module_name, j)) {
10521056
/* print module name with colon, it does not equal to the parent one */
10531057
if (count + j > buf_len) {
1054-
LOGINT(ctx);
10551058
lyxp_expr_free(exp);
1056-
return 0;
1059+
LOGBUF(cur_expr);
1060+
return -1;
10571061
}
10581062
strncpy(&buf[count], cur_expr, j);
10591063
count += j;
@@ -1062,17 +1066,17 @@ make_canonical(struct ly_ctx *ctx, int type, const char **value, void *data1, vo
10621066

10631067
/* copy the rest */
10641068
if (count + (exp->tok_len[i] - j) > buf_len) {
1065-
LOGINT(ctx);
10661069
lyxp_expr_free(exp);
1067-
return 0;
1070+
LOGBUF(end);
1071+
return -1;
10681072
}
10691073
strncpy(&buf[count], end, exp->tok_len[i] - j);
10701074
count += exp->tok_len[i] - j;
10711075
} else {
10721076
if (count + exp->tok_len[i] > buf_len) {
1073-
LOGINT(ctx);
10741077
lyxp_expr_free(exp);
1075-
return 0;
1078+
LOGBUF(&exp->expr[exp->expr_pos[i]]);
1079+
return -1;
10761080
}
10771081
strncpy(&buf[count], &exp->expr[exp->expr_pos[i]], exp->tok_len[i]);
10781082
count += exp->tok_len[i];
@@ -1081,7 +1085,7 @@ make_canonical(struct ly_ctx *ctx, int type, const char **value, void *data1, vo
10811085
if (count > buf_len) {
10821086
LOGINT(ctx);
10831087
lyxp_expr_free(exp);
1084-
return 0;
1088+
return -1;
10851089
}
10861090
buf[count] = '\0';
10871091

@@ -1146,6 +1150,8 @@ make_canonical(struct ly_ctx *ctx, int type, const char **value, void *data1, vo
11461150
}
11471151

11481152
return 0;
1153+
1154+
#undef LOGBUF
11491155
}
11501156

11511157
static const char *
@@ -1412,7 +1418,10 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
14121418
c = c + len;
14131419
}
14141420

1415-
make_canonical(ctx, LY_TYPE_BITS, value_, bits, &type->info.bits.count);
1421+
if (make_canonical(ctx, LY_TYPE_BITS, value_, bits, &type->info.bits.count) == -1) {
1422+
free(bits);
1423+
goto error;
1424+
}
14161425

14171426
if (store) {
14181427
/* store the result */
@@ -1470,7 +1479,9 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
14701479
goto error;
14711480
}
14721481

1473-
make_canonical(ctx, LY_TYPE_DEC64, value_, &num, &type->info.dec64.dig);
1482+
if (make_canonical(ctx, LY_TYPE_DEC64, value_, &num, &type->info.dec64.dig) == -1) {
1483+
goto error;
1484+
}
14741485

14751486
if (store) {
14761487
/* store the result */
@@ -1598,7 +1609,10 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
15981609
type->parent->flags |= LYS_DFLTJSON;
15991610
}
16001611

1601-
make_canonical(ctx, LY_TYPE_IDENT, &value, (void*)lys_main_module(local_mod)->name, NULL);
1612+
if (make_canonical(ctx, LY_TYPE_IDENT, &value, (void*)lys_main_module(local_mod)->name, NULL) == -1) {
1613+
lydict_remove(ctx, value);
1614+
goto error;
1615+
}
16021616

16031617
/* replace the old value with the new one (even if they may be the same) */
16041618
lydict_remove(ctx, *value_);
@@ -1651,7 +1665,11 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
16511665
/* turn logging back on */
16521666
ly_ilo_restore(NULL, prev_ilo, NULL, 0);
16531667
} else {
1654-
if (make_canonical(ctx, LY_TYPE_INST, &value, NULL, NULL)) {
1668+
if ((c = make_canonical(ctx, LY_TYPE_INST, &value, NULL, NULL))) {
1669+
if (c == -1) {
1670+
goto error;
1671+
}
1672+
16551673
/* if a change occurred, value was removed from the dictionary so fix the pointers */
16561674
*value_ = value;
16571675
}
@@ -1749,7 +1767,9 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
17491767
goto error;
17501768
}
17511769

1752-
make_canonical(ctx, LY_TYPE_INT8, value_, &num, NULL);
1770+
if (make_canonical(ctx, LY_TYPE_INT8, value_, &num, NULL) == -1) {
1771+
goto error;
1772+
}
17531773

17541774
if (store) {
17551775
/* store the result */
@@ -1764,7 +1784,9 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
17641784
goto error;
17651785
}
17661786

1767-
make_canonical(ctx, LY_TYPE_INT16, value_, &num, NULL);
1787+
if (make_canonical(ctx, LY_TYPE_INT16, value_, &num, NULL) == -1) {
1788+
goto error;
1789+
}
17681790

17691791
if (store) {
17701792
/* store the result */
@@ -1779,7 +1801,9 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
17791801
goto error;
17801802
}
17811803

1782-
make_canonical(ctx, LY_TYPE_INT32, value_, &num, NULL);
1804+
if (make_canonical(ctx, LY_TYPE_INT32, value_, &num, NULL) == -1) {
1805+
goto error;
1806+
}
17831807

17841808
if (store) {
17851809
/* store the result */
@@ -1795,7 +1819,9 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
17951819
goto error;
17961820
}
17971821

1798-
make_canonical(ctx, LY_TYPE_INT64, value_, &num, NULL);
1822+
if (make_canonical(ctx, LY_TYPE_INT64, value_, &num, NULL) == -1) {
1823+
goto error;
1824+
}
17991825

18001826
if (store) {
18011827
/* store the result */
@@ -1810,7 +1836,9 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
18101836
goto error;
18111837
}
18121838

1813-
make_canonical(ctx, LY_TYPE_UINT8, value_, &unum, NULL);
1839+
if (make_canonical(ctx, LY_TYPE_UINT8, value_, &unum, NULL) == -1) {
1840+
goto error;
1841+
}
18141842

18151843
if (store) {
18161844
/* store the result */
@@ -1825,7 +1853,9 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
18251853
goto error;
18261854
}
18271855

1828-
make_canonical(ctx, LY_TYPE_UINT16, value_, &unum, NULL);
1856+
if (make_canonical(ctx, LY_TYPE_UINT16, value_, &unum, NULL) == -1) {
1857+
goto error;
1858+
}
18291859

18301860
if (store) {
18311861
/* store the result */
@@ -1840,7 +1870,9 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
18401870
goto error;
18411871
}
18421872

1843-
make_canonical(ctx, LY_TYPE_UINT32, value_, &unum, NULL);
1873+
if (make_canonical(ctx, LY_TYPE_UINT32, value_, &unum, NULL) == -1) {
1874+
goto error;
1875+
}
18441876

18451877
if (store) {
18461878
/* store the result */
@@ -1855,7 +1887,9 @@ lyp_parse_value(struct lys_type *type, const char **value_, struct lyxml_elem *x
18551887
goto error;
18561888
}
18571889

1858-
make_canonical(ctx, LY_TYPE_UINT64, value_, &unum, NULL);
1890+
if (make_canonical(ctx, LY_TYPE_UINT64, value_, &unum, NULL) == -1) {
1891+
goto error;
1892+
}
18591893

18601894
if (store) {
18611895
/* store the result */

0 commit comments

Comments
 (0)