]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add code that honors the "max" field in fr_sbuff_uctx_file_t (#3786)
authorJames Jones <jejones3141@gmail.com>
Tue, 5 Jan 2021 19:00:21 +0000 (13:00 -0600)
committerGitHub <noreply@github.com>
Tue, 5 Jan 2021 19:00:21 +0000 (19:00 +0000)
Note: buffering in the FILE may cause it to read more bytes
than the sbuff will be allowed to access.

src/lib/util/sbuff.c
src/lib/util/sbuff.h
src/lib/util/sbuff_tests.c

index 915ed916717e219d940c9de03a92abf385412087..914ce49398a1cfdf1565462958a60c7f6089906b 100644 (file)
@@ -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;
        }
 
index 4ad36e9e0ad1646fe080b23d539798213940f25d..ac022993ceea57579b08fedbd8f9cb40a6b0736f 100644 (file)
@@ -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) \
 })
index 385677d1f8361cfbc686a6c42e7b787ee5bcd4d6..7ee3389832e61865c21aeaa2f96378b2697a0ea8 100644 (file)
@@ -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 },