The jwt_verify converter was added in 2.5 with commit
130e142ee2
("MEDIUM: jwt: Add jwt_verify converter to verify JWT integrity"). It
takes a string on input and returns an integer. It turns out that by
presetting the return value to zero before processing contents, while
the sample data is a union, it overwrites the beginning of the buffer
struct passed on input. On a 64-bit arch it's not an issue because it's
where the allocated size is stored and it's not used in the operation,
which explains why the regtest works. But on 32-bit, both the size and
the pointer are overwritten, causing a NULL pointer to be passed to
jwt_tokenize() which is not designed to support this, hence crashes.
Let's just use a temporary variable to hold the result and move the
output sample initialization to the end of the function.
This should be backported as far as 2.5.
(cherry picked from commit
e41638af33d76660220ce2e3ed613e8a24fb6e55)
Signed-off-by: Willy Tarreau <w@1wt.eu>
static int sample_conv_jwt_verify(const struct arg *args, struct sample *smp, void *private)
{
struct sample alg_smp, key_smp;
-
- smp->data.type = SMP_T_SINT;
- smp->data.u.sint = 0;
+ enum jwt_vrfy_status ret;
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[1], &key_smp))
return 0;
- smp->data.u.sint = jwt_verify(&smp->data.u.str, &alg_smp.data.u.str,
- &key_smp.data.u.str);
+ ret = jwt_verify(&smp->data.u.str, &alg_smp.data.u.str, &key_smp.data.u.str);
+ smp->data.type = SMP_T_SINT;
+ smp->data.u.sint = ret;
return 1;
}