cjose: Fix build with clang by initializing decoded buffer lengths

_cjose_jwk_import_RSA() and _cjose_jwk_import_EC() declare their
*_buflen variables in the middle of the function, interleaved with error
paths that goto a shared cleanup label. An early decode failure jumps
over the remaining declarations, and the cleanup block then reads them
uninitialized:

| jwk.c:1501:9: error: variable 'dq_buflen' is used uninitialized
|                whenever 'if' condition is true
|                [-Werror,-Wsometimes-uninitialized]
| jwk.c:1554:39: note: uninitialized use occurs here
|     _cjose_cleanse_dealloc(dq_buffer, dq_buflen);

_cjose_cleanse_dealloc() uses the length to wipe key material, so this
is an out-of-bounds write hazard on the error path rather than just a
warning. src/Makefile.am builds with -Werror, so clang also makes it
fatal; the 0.6.2.4 -> 0.6.2.7 upgrade exposed it.

Verified on aarch64 for qemuarm64: do_compile fails before the change
with 20 such errors, and do_compile and do_package succeed after.

Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
This commit is contained in:
Khem Raj
2026-08-06 23:32:43 -07:00
parent d1384edec1
commit f0d0a6b626
2 changed files with 152 additions and 1 deletions
@@ -0,0 +1,149 @@
From 5e8337d3c0ad2b19b78098f72814fbe2442226c9 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 5 Aug 2026 19:27:04 +0000
Subject: [PATCH] jwk: initialize the decoded buffer lengths up front
_cjose_jwk_import_EC() and _cjose_jwk_import_RSA() declare their
*_buflen variables in the middle of the function, interleaved with
error paths that goto the shared cleanup label. When an early decode
fails, the goto jumps over the remaining declarations and the cleanup
block then reads them uninitialized:
| jwk.c:1501:9: error: variable 'dq_buflen' is used uninitialized
| whenever 'if' condition is true
| [-Werror,-Wsometimes-uninitialized]
| jwk.c:1554:39: note: uninitialized use occurs here
| _cjose_cleanse_dealloc(dq_buffer, dq_buflen);
_cjose_cleanse_dealloc() uses the length to wipe key material, so this
is a real out-of-bounds write hazard on the error path, not just a
warning. src/Makefile.am builds with -Werror, so it also breaks the
build with clang.
Declare the lengths alongside the buffers they pair with and assign
them where they were previously initialized.
Upstream-Status: Submitted [https://github.com/OpenIDC/cjose/pull/32]
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
src/jwk.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/src/jwk.c b/src/jwk.c
index 9c57a0b..58f872b 100644
--- a/src/jwk.c
+++ b/src/jwk.c
@@ -1371,6 +1371,9 @@ static cjose_jwk_t *_cjose_jwk_import_EC(json_t *jwk_json, cjose_err *err)
uint8_t *x_buffer = NULL;
uint8_t *y_buffer = NULL;
uint8_t *d_buffer = NULL;
+ size_t x_buflen = 0;
+ size_t y_buflen = 0;
+ size_t d_buflen = 0;
// get the value of the crv attribute
const char *crv_str = _get_json_object_string_attribute(jwk_json, CJOSE_JWK_CRV_STR, err);
@@ -1389,7 +1392,7 @@ static cjose_jwk_t *_cjose_jwk_import_EC(json_t *jwk_json, cjose_err *err)
}
// get the decoded value of the x coordinate
- size_t x_buflen = (size_t)_ec_size_for_curve(crv, err);
+ x_buflen = (size_t)_ec_size_for_curve(crv, err);
if (!_decode_json_object_base64url_attribute(jwk_json, CJOSE_JWK_X_STR, &x_buffer, &x_buflen, err))
{
CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
@@ -1397,7 +1400,7 @@ static cjose_jwk_t *_cjose_jwk_import_EC(json_t *jwk_json, cjose_err *err)
}
// get the decoded value of the y coordinate
- size_t y_buflen = (size_t)_ec_size_for_curve(crv, err);
+ y_buflen = (size_t)_ec_size_for_curve(crv, err);
if (!_decode_json_object_base64url_attribute(jwk_json, CJOSE_JWK_Y_STR, &y_buffer, &y_buflen, err))
{
CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
@@ -1405,7 +1408,7 @@ static cjose_jwk_t *_cjose_jwk_import_EC(json_t *jwk_json, cjose_err *err)
}
// get the decoded value of the private key d
- size_t d_buflen = (size_t)_ec_size_for_curve(crv, err);
+ d_buflen = (size_t)_ec_size_for_curve(crv, err);
if (!_decode_json_object_base64url_attribute(jwk_json, CJOSE_JWK_D_STR, &d_buffer, &d_buflen, err))
{
CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
@@ -1455,9 +1458,16 @@ static cjose_jwk_t *_cjose_jwk_import_RSA(json_t *jwk_json, cjose_err *err)
uint8_t *dp_buffer = NULL;
uint8_t *dq_buffer = NULL;
uint8_t *qi_buffer = NULL;
+ size_t n_buflen = 0;
+ size_t e_buflen = 0;
+ size_t d_buflen = 0;
+ size_t p_buflen = 0;
+ size_t q_buflen = 0;
+ size_t dp_buflen = 0;
+ size_t dq_buflen = 0;
+ size_t qi_buflen = 0;
// get the decoded value of n (buflen = 0 means no particular expected len)
- size_t n_buflen = 0;
if (!_decode_json_object_base64url_attribute(jwk_json, CJOSE_JWK_N_STR, &n_buffer, &n_buflen, err))
{
CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
@@ -1465,7 +1475,6 @@ static cjose_jwk_t *_cjose_jwk_import_RSA(json_t *jwk_json, cjose_err *err)
}
// get the decoded value of e
- size_t e_buflen = 0;
if (!_decode_json_object_base64url_attribute(jwk_json, CJOSE_JWK_E_STR, &e_buffer, &e_buflen, err))
{
CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
@@ -1473,7 +1482,6 @@ static cjose_jwk_t *_cjose_jwk_import_RSA(json_t *jwk_json, cjose_err *err)
}
// get the decoded value of d
- size_t d_buflen = 0;
if (!_decode_json_object_base64url_attribute(jwk_json, CJOSE_JWK_D_STR, &d_buffer, &d_buflen, err))
{
CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
@@ -1481,7 +1489,6 @@ static cjose_jwk_t *_cjose_jwk_import_RSA(json_t *jwk_json, cjose_err *err)
}
// get the decoded value of p
- size_t p_buflen = 0;
if (!_decode_json_object_base64url_attribute(jwk_json, CJOSE_JWK_P_STR, &p_buffer, &p_buflen, err))
{
CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
@@ -1489,7 +1496,6 @@ static cjose_jwk_t *_cjose_jwk_import_RSA(json_t *jwk_json, cjose_err *err)
}
// get the decoded value of q
- size_t q_buflen = 0;
if (!_decode_json_object_base64url_attribute(jwk_json, CJOSE_JWK_Q_STR, &q_buffer, &q_buflen, err))
{
CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
@@ -1497,7 +1503,6 @@ static cjose_jwk_t *_cjose_jwk_import_RSA(json_t *jwk_json, cjose_err *err)
}
// get the decoded value of dp
- size_t dp_buflen = 0;
if (!_decode_json_object_base64url_attribute(jwk_json, CJOSE_JWK_DP_STR, &dp_buffer, &dp_buflen, err))
{
CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
@@ -1505,7 +1510,6 @@ static cjose_jwk_t *_cjose_jwk_import_RSA(json_t *jwk_json, cjose_err *err)
}
// get the decoded value of dq
- size_t dq_buflen = 0;
if (!_decode_json_object_base64url_attribute(jwk_json, CJOSE_JWK_DQ_STR, &dq_buffer, &dq_buflen, err))
{
CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
@@ -1513,7 +1517,6 @@ static cjose_jwk_t *_cjose_jwk_import_RSA(json_t *jwk_json, cjose_err *err)
}
// get the decoded value of qi
- size_t qi_buflen = 0;
if (!_decode_json_object_base64url_attribute(jwk_json, CJOSE_JWK_QI_STR, &qi_buffer, &qi_buflen, err))
{
CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
--
2.43.0
@@ -3,7 +3,9 @@ HOMEPAGE = "https://github.com/OpenIDC/cjose"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE;md5=7249e2f9437adfb8c88d870438042f0e"
SRC_URI = "git://github.com/OpenIDC/cjose;protocol=https;branch=version-0.6.2.x;tag=v${PV}"
SRC_URI = "git://github.com/OpenIDC/cjose;protocol=https;branch=version-0.6.2.x;tag=v${PV} \
file://0001-jwk-initialize-the-decoded-buffer-lengths-up-front.patch \
"
SRCREV = "10af8915a666b50caa5500cdc3f2523b916be720"