[njs] Fixed access to uninitialized alg in SubtleCrypto.import().

noreply at nginx.com noreply at nginx.com
Wed Feb 19 00:31:02 UTC 2025


details:   https://github.com/nginx/njs/commit/0b6eca0a123000297d4e18d46770bad7416d5056
branches:  master
commit:    0b6eca0a123000297d4e18d46770bad7416d5056
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Tue, 11 Feb 2025 16:41:56 -0800
description:
Fixed access to uninitialized alg in SubtleCrypto.import().

Found by GCC:
In function ‘qjs_import_jwk_oct’,
external/qjs_webcrypto_module.c:3116:13: error: ‘alg.start’ may be used uninitialized [-Werror=maybe-uninitialized]
 3116 |             JS_ThrowTypeError(cx, "key size and \"alg\" value \"%s\" mismatch",

The similar place in the NJS module was also fixed.

---
 external/njs_webcrypto_module.c | 47 +++++++++++++++++---------------
 external/qjs_webcrypto_module.c | 59 ++++++++++++++++++++---------------------
 2 files changed, 54 insertions(+), 52 deletions(-)

diff --git a/external/njs_webcrypto_module.c b/external/njs_webcrypto_module.c
index d4725d89..59d02c1d 100644
--- a/external/njs_webcrypto_module.c
+++ b/external/njs_webcrypto_module.c
@@ -3207,37 +3207,40 @@ njs_import_jwk_oct(njs_vm_t *vm, njs_value_t *jwk, njs_webcrypto_key_t *key)
 
     njs_decode_base64url(&key->u.s.raw, &b64);
 
-    size = 16;
-
     val = njs_vm_object_prop(vm, jwk, &string_alg, &value);
-    if (val != NULL && njs_value_is_string(val)) {
-        njs_value_string_get(val, &alg);
+    if (njs_slow_path(val == NULL || !njs_value_is_string(val))) {
+        njs_vm_type_error(vm, "Invalid JWK oct alg");
+        return NJS_ERROR;
+    }
 
-        if (key->alg->type == NJS_ALGORITHM_HMAC) {
-            for (w = &hashes[0]; w->name.length != 0; w++) {
-                if (njs_strstr_eq(&alg, &w->name)) {
-                    key->hash = w->value;
-                    goto done;
-                }
-            }
+    njs_value_string_get(val, &alg);
 
-        } else {
-            type = key->alg->type;
-            a = &njs_webcrypto_alg_aes_name[type - NJS_ALGORITHM_AES_GCM][0];
-            for (; a->length != 0; a++) {
-                if (njs_strstr_eq(&alg, a)) {
-                    goto done;
-                }
+    size = 16;
 
-                size += 8;
+    if (key->alg->type == NJS_ALGORITHM_HMAC) {
+        for (w = &hashes[0]; w->name.length != 0; w++) {
+            if (njs_strstr_eq(&alg, &w->name)) {
+                key->hash = w->value;
+                goto done;
             }
         }
 
-        njs_vm_type_error(vm, "unexpected \"alg\" value \"%V\" for JWK key",
-                          &alg);
-        return NJS_ERROR;
+    } else {
+        type = key->alg->type;
+        a = &njs_webcrypto_alg_aes_name[type - NJS_ALGORITHM_AES_GCM][0];
+        for (; a->length != 0; a++) {
+            if (njs_strstr_eq(&alg, a)) {
+                goto done;
+            }
+
+            size += 8;
+        }
     }
 
+    njs_vm_type_error(vm, "unexpected \"alg\" value \"%V\" for JWK key",
+                      &alg);
+    return NJS_ERROR;
+
 done:
 
     if (key->alg->type != NJS_ALGORITHM_HMAC) {
diff --git a/external/qjs_webcrypto_module.c b/external/qjs_webcrypto_module.c
index 22f5d108..64098f4e 100644
--- a/external/qjs_webcrypto_module.c
+++ b/external/qjs_webcrypto_module.c
@@ -3064,50 +3064,49 @@ qjs_import_jwk_oct(JSContext *cx, JSValue jwk, qjs_webcrypto_key_t *key)
     qjs_base64url_decode(cx, &b64, &key->u.s.raw);
     JS_FreeCString(cx, (char *) b64.start);
 
-    size = 16;
-
     val = JS_GetPropertyStr(cx, jwk, "alg");
     if (JS_IsException(val)) {
         return JS_EXCEPTION;
     }
 
-    if (JS_IsString(val)) {
-        alg.start = (u_char *) JS_ToCStringLen(cx, &alg.length, val);
+    if (!JS_IsString(val)) {
         JS_FreeValue(cx, val);
-        val = JS_UNDEFINED;
-
-        if (alg.start == NULL) {
-            JS_ThrowOutOfMemory(cx);
-            return JS_EXCEPTION;
-        }
+        return JS_ThrowTypeError(cx, "Invalid JWK oct alg");
+    }
 
-        if (key->alg->type == QJS_ALGORITHM_HMAC) {
-            for (w = &hashes[0]; w->name.length != 0; w++) {
-                if (njs_strstr_eq(&alg, &w->name)) {
-                    key->hash = w->value;
-                    goto done;
-                }
-            }
+    alg.start = (u_char *) JS_ToCStringLen(cx, &alg.length, val);
+    JS_FreeValue(cx, val);
+    if (alg.start == NULL) {
+        JS_ThrowOutOfMemory(cx);
+        return JS_EXCEPTION;
+    }
 
-        } else {
-            type = key->alg->type;
-            a = &qjs_webcrypto_alg_aes_name[type - QJS_ALGORITHM_AES_GCM][0];
-            for (; a->length != 0; a++) {
-                if (njs_strstr_eq(&alg, a)) {
-                    goto done;
-                }
+    size = 16;
 
-                size += 8;
+    if (key->alg->type == QJS_ALGORITHM_HMAC) {
+        for (w = &hashes[0]; w->name.length != 0; w++) {
+            if (njs_strstr_eq(&alg, &w->name)) {
+                key->hash = w->value;
+                goto done;
             }
         }
 
-        JS_ThrowTypeError(cx, "unexpected \"alg\" value \"%s\" for JWK key",
-                          alg.start);
-        JS_FreeCString(cx, (char *) alg.start);
-        return JS_EXCEPTION;
+    } else {
+        type = key->alg->type;
+        a = &qjs_webcrypto_alg_aes_name[type - QJS_ALGORITHM_AES_GCM][0];
+        for (; a->length != 0; a++) {
+            if (njs_strstr_eq(&alg, a)) {
+                goto done;
+            }
+
+            size += 8;
+        }
     }
 
-    JS_FreeValue(cx, val);
+    JS_ThrowTypeError(cx, "unexpected \"alg\" value \"%s\" for JWK key",
+                      alg.start);
+    JS_FreeCString(cx, (char *) alg.start);
+    return JS_EXCEPTION;
 
 done:
 


More information about the nginx-devel mailing list