From: James Jones Date: Tue, 5 Jan 2021 19:00:21 +0000 (-0600) Subject: Add code that honors the "max" field in fr_sbuff_uctx_file_t (#3786) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2efcb2a4a93549b11bb4765be245b66246dc0449;p=thirdparty%2Ffreeradius-server.git Add code that honors the "max" field in fr_sbuff_uctx_file_t (#3786) Note: buffering in the FILE may cause it to read more bytes than the sbuff will be allowed to access. --- diff --git a/src/lib/util/sbuff.c b/src/lib/util/sbuff.c index 915ed916717..914ce49398a 100644 --- a/src/lib/util/sbuff.c +++ b/src/lib/util/sbuff.c @@ -232,7 +232,7 @@ size_t fr_sbuff_shift(fr_sbuff_t *sbuff, size_t shift) */ size_t fr_sbuff_extend_file(fr_sbuff_t *sbuff, size_t extension) { - size_t read, available; + size_t read, available, total_read; fr_sbuff_uctx_file_t *fctx; CHECK_SBUFF_INIT(sbuff); @@ -242,6 +242,12 @@ size_t fr_sbuff_extend_file(fr_sbuff_t *sbuff, size_t extension) if (extension == SIZE_MAX) extension = 0; + total_read = sbuff->shifted + (sbuff->end - sbuff->buff); + if (total_read >= fctx->max) { + fr_strerror_const("Can't satisfy extension request, max bytes read"); + return 0; /* There's no way we could satisfy the extension request */ + } + if (fr_sbuff_used(sbuff)) { /* * Try and shift as much as we can out @@ -253,6 +259,7 @@ size_t fr_sbuff_extend_file(fr_sbuff_t *sbuff, size_t extension) } available = fctx->buff_end - sbuff->end; + if (available > (fctx->max - total_read)) available = fctx->max - total_read; if (available < extension) { fr_strerror_printf("Can't satisfy extension request for %zu bytes", extension); return 0; /* There's no way we could satisfy the extension request */ @@ -1945,7 +1952,7 @@ bool fr_sbuff_is_terminal(fr_sbuff_t *in, fr_sbuff_term_t const *tt) (status & FR_SBUFF_EXTEND_ERROR) == 0) { return true; } - + return false; } diff --git a/src/lib/util/sbuff.h b/src/lib/util/sbuff.h index 4ad36e9e0ad..ac022993cee 100644 --- a/src/lib/util/sbuff.h +++ b/src/lib/util/sbuff.h @@ -366,6 +366,7 @@ do { \ .p = (_sbuff)->p, \ .is_const = (_sbuff)->is_const, \ .extend = (_sbuff)->extend, \ + .shifted = (_sbuff)->shifted, \ .uctx = (_sbuff)->uctx, \ .parent = (_sbuff) \ }) @@ -383,6 +384,7 @@ do { \ .is_const = (_sbuff)->is_const, \ .adv_parent = 1, \ .extend = (_sbuff)->extend, \ + .shifted = (_sbuff)->shifted, \ .uctx = (_sbuff)->uctx, \ .parent = (_sbuff) \ }) diff --git a/src/lib/util/sbuff_tests.c b/src/lib/util/sbuff_tests.c index 385677d1f83..7ee3389832e 100644 --- a/src/lib/util/sbuff_tests.c +++ b/src/lib/util/sbuff_tests.c @@ -963,6 +963,28 @@ static void test_file_extend(void) fclose(fp); } +static void test_file_extend_max(void) +{ + fr_sbuff_t sbuff; + fr_sbuff_uctx_file_t fctx; + FILE *fp; + char buff[16]; + char fbuff[] = " xyzzy"; + char *post_ws; + + TEST_CASE("Initialization"); + fp = fmemopen(fbuff, sizeof(fbuff) - 1, "r"); + TEST_CHECK(fp != NULL); + TEST_CHECK(fr_sbuff_init_file(&sbuff, &fctx, buff, sizeof(buff), fp, sizeof(fbuff) - 8) == &sbuff); + + TEST_CASE("Confirm that max stops us from seeing xyzzy"); + TEST_CHECK_LEN(sizeof(fbuff) - 8, fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL)); + (void) fr_sbuff_out_abstrncpy(NULL, &post_ws, &sbuff, 24); + TEST_CHECK_STRCMP(post_ws, ""); + talloc_free(post_ws); + fclose(fp); +} + static void test_adv_past_str(void) { fr_sbuff_t sbuff; @@ -1429,6 +1451,7 @@ TEST_LIST = { { "fr_sbuff_talloc_extend_multi_level", test_talloc_extend_multi_level }, { "fr_sbuff_talloc_extend_with_marker", test_talloc_extend_with_marker }, { "fr_sbuff_file_extend", test_file_extend }, + { "fr_sbuff_file_extend_max", test_file_extend_max }, { "fr_sbuff_no_advance", test_no_advance },