]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: sample: properly verify that variables cast to sample
authorWilly Tarreau <w@1wt.eu>
Wed, 6 Oct 2021 13:30:52 +0000 (15:30 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 6 Oct 2021 23:36:51 +0000 (01:36 +0200)
The various variable-to-sample converters allow to turn a variable to
a sample of type string, sint or binary, but both the string one used
by strcmp() and the binary one used by secure_memcmp() are missing a
pointer check on the ability to the cast, making them crash if a
variable of type addr is used with strcmp(), or if an addr or bool is
used with secure_memcmp().

Let's rely on the new sample_conv_var2smp() function to run the proper
checks.

This will need to be backported to all supported version. It relies on
previous commits:

  CLEANUP: server: always include the storage for SSL settings
  CLEANUP: sample: rename sample_conv_var2smp() to *_sint
  CLEANUP: sample: uninline sample_conv_var2smp_str()
  MINOR: sample: provide a generic var-to-sample conversion function

For backports it's probably easier to check the sample_casts[] pointer
before calling it in sample_conv_strcmp() and sample_conv_secure_memcmp().

src/sample.c

index 7cee16c34bcc65760c4665a3aedff94f26731196..00b820241123e8e9d95bc8b9a17860e2cdd590b0 100644 (file)
@@ -1771,13 +1771,7 @@ int sample_conv_var2smp_str(const struct arg *arg, struct sample *smp)
                smp->flags = SMP_F_CONST;
                return 1;
        case ARGT_VAR:
-               if (!vars_get_by_desc(&arg->data.var, smp, NULL))
-                               return 0;
-               if (!sample_casts[smp->data.type][SMP_T_STR])
-                               return 0;
-               if (!sample_casts[smp->data.type][SMP_T_STR](smp))
-                               return 0;
-               return 1;
+               return sample_conv_var2smp(&arg->data.var, smp, SMP_T_STR);
        default:
                return 0;
        }
@@ -3014,13 +3008,7 @@ int sample_conv_var2smp_sint(const struct arg *arg, struct sample *smp)
                smp->data.u.sint = arg->data.sint;
                return 1;
        case ARGT_VAR:
-               if (!vars_get_by_desc(&arg->data.var, smp, NULL))
-                       return 0;
-               if (!sample_casts[smp->data.type][SMP_T_SINT])
-                       return 0;
-               if (!sample_casts[smp->data.type][SMP_T_SINT](smp))
-                       return 0;
-               return 1;
+               return sample_conv_var2smp(&arg->data.var, smp, SMP_T_SINT);
        default:
                return 0;
        }
@@ -3401,9 +3389,8 @@ static int sample_conv_strcmp(const struct arg *arg_p, struct sample *smp, void
        smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
        if (arg_p[0].type != ARGT_VAR)
                return 0;
-       if (!vars_get_by_desc(&arg_p[0].data.var, &tmp, NULL))
-               return 0;
-       if (!sample_casts[tmp.data.type][SMP_T_STR](&tmp))
+
+       if (!sample_conv_var2smp(&arg_p[0].data.var, &tmp, SMP_T_STR))
                return 0;
 
        max = MIN(smp->data.u.str.data, tmp.data.u.str.data);
@@ -3439,9 +3426,8 @@ static int sample_conv_secure_memcmp(const struct arg *arg_p, struct sample *smp
        smp_set_owner(&tmp, smp->px, smp->sess, smp->strm, smp->opt);
        if (arg_p[0].type != ARGT_VAR)
                return 0;
-       if (!vars_get_by_desc(&arg_p[0].data.var, &tmp, NULL))
-               return 0;
-       if (!sample_casts[tmp.data.type][SMP_T_BIN](&tmp))
+
+       if (!sample_conv_var2smp(&arg_p[0].data.var, &tmp, SMP_T_BIN))
                return 0;
 
        if (smp->data.u.str.data != tmp.data.u.str.data) {