BUG/MINOR: jwt: Copy input and parameters in dedicated buffers in jwt_verify converter
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Mon, 30 Jun 2025 14:56:22 +0000 (16:56 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 1 Oct 2025 13:40:17 +0000 (15:40 +0200)
When resolving variable values the temporary trash chunks are used so
when calling the 'jwt_verify' converter with two variable parameters
like in the following line, the input would be overwritten by the value
of the second parameter :
    var(txn.bearer),jwt_verify(txn.jwt_alg,txn.cert)
Copying the values into dedicated alloc'ed buffers prevents any new call
to get_trash_chunk from erasing the data we need in the converter.

This patch can be backported up to 2.8.

(cherry picked from commit 3465f88f8ab9c3f163d73938765f741c2b7e6a67)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 33eb0792afff79fa9cd596e87e4796f6d518d2c7)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 47a40f66d72d3be619b2db6c2639f584a4e861b1)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>

src/sample.c

index 811d81e..f9d0ea9 100644 (file)
@@ -4486,19 +4486,53 @@ static int sample_conv_jwt_verify(const struct arg *args, struct sample *smp, vo
 {
        struct sample alg_smp, key_smp;
        enum jwt_vrfy_status ret;
+       struct buffer *input = NULL;
+       struct buffer *alg = NULL;
+       struct buffer *key = NULL;
+       int retval = 0;
+
+       /* The two following calls to 'sample_conv_var2smp_str' will both make
+        * use of the preallocated trash buffer (via get_trash_chunk call in
+        * smp_dup) which would end up erasing the contents of the 'smp' input
+        * buffer.
+        */
+       input = alloc_trash_chunk();
+       if (!input)
+               return 0;
+       alg = alloc_trash_chunk();
+       if (!alg)
+               goto end;
+       key = alloc_trash_chunk();
+       if (!key)
+               goto end;
+
+       if (!chunk_cpy(input, &smp->data.u.str))
+               goto end;
 
        smp_set_owner(&alg_smp, smp->px, smp->sess, smp->strm, smp->opt);
-       smp_set_owner(&key_smp, smp->px, smp->sess, smp->strm, smp->opt);
        if (!sample_conv_var2smp_str(&args[0], &alg_smp))
-               return 0;
+               goto end;
+       if (chunk_printf(alg, "%.*s", (int)b_data(&alg_smp.data.u.str), b_orig(&alg_smp.data.u.str)) <= 0)
+               goto end;
+
+       smp_set_owner(&key_smp, smp->px, smp->sess, smp->strm, smp->opt);
        if (!sample_conv_var2smp_str(&args[1], &key_smp))
-               return 0;
+               goto end;
+       if (chunk_printf(key, "%.*s", (int)b_data(&key_smp.data.u.str), b_orig(&key_smp.data.u.str)) <= 0)
+               goto end;
 
-       ret = jwt_verify(&smp->data.u.str,  &alg_smp.data.u.str, &key_smp.data.u.str);
+       ret = jwt_verify(input, alg, key);
 
        smp->data.type = SMP_T_SINT;
        smp->data.u.sint = ret;
-       return 1;
+
+       retval = 1;
+
+end:
+       free_trash_chunk(input);
+       free_trash_chunk(alg);
+       free_trash_chunk(key);
+       return retval;
 }