Skip to content

Commit 9d9d6b6

Browse files
committed
Debug
1 parent cfdc3a8 commit 9d9d6b6

File tree

6 files changed

+267
-25
lines changed

6 files changed

+267
-25
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
if [ "$#" -lt 4 ]; then
5+
echo "Usage: $0 <timeout_sec> <log_file> -- <command> [args...]" >&2
6+
exit 2
7+
fi
8+
9+
TIMEOUT_SEC="$1"
10+
LOG_FILE="$2"
11+
shift 2
12+
13+
if [ "$1" != "--" ]; then
14+
echo "Missing '--' separator before command" >&2
15+
exit 2
16+
fi
17+
shift
18+
19+
if [ "$#" -eq 0 ]; then
20+
echo "Missing command to execute" >&2
21+
exit 2
22+
fi
23+
24+
HEARTBEAT_SEC="${WATCHDOG_HEARTBEAT_SEC:-60}"
25+
POLL_SEC=5
26+
27+
echo "[watchdog] timeout=${TIMEOUT_SEC}s heartbeat=${HEARTBEAT_SEC}s log=${LOG_FILE}"
28+
echo "[watchdog] command: $*"
29+
30+
# Run command in isolated process group so timeout handling can terminate
31+
# the entire subtree.
32+
setsid "$@" >"$LOG_FILE" 2>&1 &
33+
CMD_PID=$!
34+
CMD_PGID="$CMD_PID"
35+
START_TS="$(date +%s)"
36+
37+
dump_diagnostics() {
38+
echo "[watchdog] diagnostics begin"
39+
echo "[watchdog] tail ${LOG_FILE}"
40+
tail -n 200 "$LOG_FILE" || true
41+
42+
echo "[watchdog] process snapshot"
43+
ps -eo pid,ppid,pgid,etime,comm,args | awk -v pgid="$CMD_PGID" '$3 == pgid { print }' || true
44+
45+
if command -v gdb >/dev/null 2>&1; then
46+
while read -r pid _; do
47+
[ -n "${pid:-}" ] || continue
48+
echo "[watchdog] gdb backtrace pid=${pid}"
49+
gdb -q -batch -ex "set pagination off" -ex "thread apply all bt" -p "$pid" || true
50+
done < <(ps -eo pid,pgid | awk -v pgid="$CMD_PGID" '$2 == pgid { print $1, $2 }')
51+
else
52+
echo "[watchdog] gdb not found; skipping stack dumps"
53+
fi
54+
echo "[watchdog] diagnostics end"
55+
}
56+
57+
while kill -0 "$CMD_PID" 2>/dev/null; do
58+
NOW_TS="$(date +%s)"
59+
ELAPSED="$((NOW_TS - START_TS))"
60+
61+
if [ "${NEXT_HEARTBEAT_TS:-0}" -le "$NOW_TS" ]; then
62+
LAST_LINE="$(tail -n 1 "$LOG_FILE" 2>/dev/null || true)"
63+
echo "[watchdog] elapsed=${ELAPSED}s last='${LAST_LINE}'"
64+
NEXT_HEARTBEAT_TS="$((NOW_TS + HEARTBEAT_SEC))"
65+
fi
66+
67+
if [ "$ELAPSED" -ge "$TIMEOUT_SEC" ]; then
68+
echo "[watchdog] timeout reached after ${ELAPSED}s"
69+
dump_diagnostics
70+
71+
kill -TERM -- "-${CMD_PGID}" 2>/dev/null || true
72+
sleep 5
73+
kill -KILL -- "-${CMD_PGID}" 2>/dev/null || true
74+
75+
wait "$CMD_PID" || true
76+
exit 124
77+
fi
78+
79+
sleep "$POLL_SEC"
80+
done
81+
82+
set +e
83+
wait "$CMD_PID"
84+
RC=$?
85+
set -e
86+
87+
cat "$LOG_FILE"
88+
exit "$RC"

.github/workflows/build-and-test.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ jobs:
3939

4040
# Build and test ASAN build, with wolfCrypt tests enabled.
4141
- name: Build and test ASAN TESTWOLFCRYPT
42-
run: cd test && make clean && make -j ASAN=1 TESTWOLFCRYPT=1 WOLFSSL_DIR=../wolfssl && make run
42+
run: cd test && make clean && make -j ASAN=1 TESTWOLFCRYPT=1 WOLFSSL_DIR=../wolfssl && ../.github/scripts/run-with-watchdog.sh 2700 /tmp/wh_test_asan_testwolfcrypt.log -- make run
4343

4444
# Build and test ASAN build, with wolfCrypt tests enabled and using the DMA devId.
4545
- name: Build and test ASAN TESTWOLFCRYPT TESTWOLFCRYPT_DMA
46-
run: cd test && make clean && make -j ASAN=1 TESTWOLFCRYPT=1 TESTWOLFCRYPT_DMA=1 DMA=1 WOLFSSL_DIR=../wolfssl && make run
46+
run: cd test && make clean && make -j ASAN=1 TESTWOLFCRYPT=1 TESTWOLFCRYPT_DMA=1 DMA=1 WOLFSSL_DIR=../wolfssl && ../.github/scripts/run-with-watchdog.sh 2700 /tmp/wh_test_asan_testwolfcrypt_dma.log -- make run
4747

4848
# Build and test debug build with ASAN and NOCRYPTO
4949
- name: Build and test ASAN DEBUG NOCRYPTO
@@ -71,8 +71,8 @@ jobs:
7171

7272
# Build and test in multithreaded mode with everything enabled and wolfCrypt tests
7373
- name: Build and test with THREADSAFE and TESTWOLFCRYPT and everything
74-
run: cd test && make clean && make -j THREADSAFE=1 TESTWOLFCRYPT=1 DMA=1 SHE=1 ASAN=1 WOLFSSL_DIR=../wolfssl && make run
74+
run: cd test && make clean && make -j THREADSAFE=1 TESTWOLFCRYPT=1 DMA=1 SHE=1 ASAN=1 WOLFSSL_DIR=../wolfssl && ../.github/scripts/run-with-watchdog.sh 2700 /tmp/wh_test_threadsafe_testwolfcrypt.log -- make run
7575

7676
# Build and test in multithreaded mode with everything enabled and wolfCrypt tests with dma
7777
- name: Build and test with THREADSAFE and TESTWOLFCRYPT with DMA
78-
run: cd test && make clean && make -j THREADSAFE=1 TESTWOLFCRYPT=1 TESTWOLFCRYPT_DMA=1 DMA=1 SHE=1 ASAN=1 WOLFSSL_DIR=../wolfssl && make run
78+
run: cd test && make clean && make -j THREADSAFE=1 TESTWOLFCRYPT=1 TESTWOLFCRYPT_DMA=1 DMA=1 SHE=1 ASAN=1 WOLFSSL_DIR=../wolfssl && ../.github/scripts/run-with-watchdog.sh 2700 /tmp/wh_test_threadsafe_testwolfcrypt_dma.log -- make run

src/wh_transport_mem.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ int wh_TransportMem_RecvResponse(void* c, uint16_t* out_len, void* data)
169169
return WH_ERROR_NOTREADY;
170170
}
171171

172+
/* Guard against transient/torn CSR reads and corrupted len values. */
173+
if (resp.s.len > (context->resp_size - sizeof(whTransportMemCsr))) {
174+
return WH_ERROR_NOTREADY;
175+
}
176+
172177
if ((data != NULL) && (resp.s.len != 0)) {
173178
wh_Utils_memcpy_invalidate(data, context->resp_data, resp.s.len);
174179
}
@@ -253,6 +258,11 @@ int wh_TransportMem_RecvRequest(void* c, uint16_t* out_len, void* data)
253258
return WH_ERROR_NOTREADY;
254259
}
255260

261+
/* Guard against transient/torn CSR reads and corrupted len values. */
262+
if (req.s.len > (context->req_size - sizeof(whTransportMemCsr))) {
263+
return WH_ERROR_NOTREADY;
264+
}
265+
256266
if ((data != NULL) && (req.s.len != 0)) {
257267
wh_Utils_memcpy_invalidate(data, context->req_data, req.s.len);
258268
}
@@ -262,4 +272,4 @@ int wh_TransportMem_RecvRequest(void* c, uint16_t* out_len, void* data)
262272

263273
return 0;
264274
}
265-
#endif /* WOLFHSM_CFG_ENABLE_SERVER */
275+
#endif /* WOLFHSM_CFG_ENABLE_SERVER */

test/wh_test_crypto.c

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,10 @@ static int whTest_CryptoEcc(whClientContext* ctx, int devId, WC_RNG* rng)
457457
}
458458
/* Test ECDSA sign/verify with exported keys */
459459
if (ret == 0) {
460+
WH_TEST_PRINT("ECC export key SIGN/VERIFY: begin\n");
460461
memcpy(hash, shared_ba, sizeof(hash));
461462
word32 sigLen = sizeof(sig);
463+
WH_TEST_PRINT("ECC export key SIGN/VERIFY: signing...\n");
462464
ret = wc_ecc_sign_hash((void*)hash, sizeof(hash),
463465
(void*)sig, &sigLen, rng, bobKey);
464466
if (ret != 0) {
@@ -467,6 +469,7 @@ static int whTest_CryptoEcc(whClientContext* ctx, int devId, WC_RNG* rng)
467469
}
468470
else {
469471
int res = 0;
472+
WH_TEST_PRINT("ECC export key SIGN/VERIFY: verifying...\n");
470473
ret =
471474
wc_ecc_verify_hash((void*)sig, sigLen, (void*)hash,
472475
sizeof(hash), &res, bobKey);
@@ -484,8 +487,10 @@ static int whTest_CryptoEcc(whClientContext* ctx, int devId, WC_RNG* rng)
484487
}
485488
}
486489
}
490+
WH_TEST_PRINT("ECC export key test: freeing aliceKey\n");
487491
wc_ecc_free(aliceKey);
488492
}
493+
WH_TEST_PRINT("ECC export key test: freeing bobKey\n");
489494
wc_ecc_free(bobKey);
490495
}
491496
}
@@ -675,7 +680,15 @@ static int whTest_CryptoEccCacheDuplicate(whClientContext* client)
675680
}
676681

677682
if (!WH_KEYID_ISERASED(keyId)) {
678-
wh_Client_KeyEvict(client, keyId);
683+
WH_TEST_PRINT(" Cleaning up duplicate ECC cache key (keyId=0x%X)...\n",
684+
keyId);
685+
ret = wh_Client_KeyEvict(client, keyId);
686+
if (ret != WH_ERROR_OK) {
687+
WH_ERROR_PRINT(" FAIL: wh_Client_KeyEvict returned %d\n", ret);
688+
}
689+
else {
690+
WH_TEST_PRINT(" PASS: Duplicate ECC cache key evicted\n");
691+
}
679692
}
680693

681694
return ret;
@@ -1029,6 +1042,8 @@ static int whTest_CryptoEd25519Inline(whClientContext* ctx, int devId,
10291042
byte pubKeyRaw[ED25519_PUB_KEY_SIZE];
10301043
word32 pubKeySize = sizeof(pubKeyRaw);
10311044

1045+
WH_TEST_PRINT("Testing Ed25519 inline DEVID=0x%X...\n", devId);
1046+
10321047
ret = wc_ed25519_init_ex(key, NULL, devId);
10331048
if (ret != 0) {
10341049
WH_ERROR_PRINT("Failed to initialize Ed25519 key: %d\n", ret);
@@ -1117,6 +1132,8 @@ static int whTest_CryptoEd25519ServerKey(whClientContext* ctx, int devId,
11171132
int verified = 0;
11181133
uint8_t label[] = "Ed25519 Server Key";
11191134

1135+
WH_TEST_PRINT("Testing Ed25519 server key DEVID=0x%X...\n", devId);
1136+
11201137
ret = wc_ed25519_init_ex(key, NULL, devId);
11211138
if (ret != 0) {
11221139
WH_ERROR_PRINT("Failed to initialize Ed25519 key: %d\n", ret);
@@ -1220,6 +1237,8 @@ static int whTest_CryptoEd25519Dma(whClientContext* ctx, int devId, WC_RNG* rng)
12201237
int verified = 0;
12211238
uint8_t label[] = "Ed25519 DMA Key";
12221239

1240+
WH_TEST_PRINT("Testing Ed25519 DMA DEVID=0x%X...\n", devId);
1241+
12231242
ret = wc_ed25519_init_ex(key, NULL, devId);
12241243
if (ret != 0) {
12251244
WH_ERROR_PRINT("Failed to initialize Ed25519 key (DMA): %d\n", ret);
@@ -1312,6 +1331,8 @@ static int whTest_CryptoCurve25519(whClientContext* ctx, int devId, WC_RNG* rng)
13121331
uint8_t label_b[WH_NVM_LABEL_LEN] = "Curve25519 Label B";
13131332
word32 len = 0;
13141333

1334+
WH_TEST_PRINT("Testing Curve25519 DEVID=0x%X...\n", devId);
1335+
13151336
/* Use wolfcrypt ephemeral local keys */
13161337
ret = wc_curve25519_init_ex(key_a, NULL, devId);
13171338
if (ret != 0) {
@@ -2766,9 +2787,11 @@ static int whTest_KeyCache(whClientContext* ctx, int devId, WC_RNG* rng)
27662787
}
27672788

27682789
#ifdef WOLFHSM_CFG_DMA
2790+
WH_TEST_PRINT("KEY CACHE: entering DMA-specific tests\n");
27692791
/* test cache/export using DMA */
27702792
if (ret == 0) {
27712793
keyId = WH_KEYID_ERASED;
2794+
WH_TEST_PRINT("KEY CACHE DMA: cache/export test begin\n");
27722795
ret =
27732796
whTest_CacheExportKeyDma(ctx, &keyId, labelIn, labelOut,
27742797
sizeof(labelIn), key, keyOut, sizeof(key));
@@ -3128,6 +3151,9 @@ static int whTestCrypto_Aes(whClientContext* ctx, int devId, WC_RNG* rng)
31283151
uint8_t plainOut[WH_TEST_AES_TEXTSIZE] = { 0 };
31293152
whKeyId keyId = WH_KEYID_ERASED;
31303153
uint8_t labelIn[WH_NVM_LABEL_LEN] = "AES Key Label";
3154+
int evictRet = WH_ERROR_OK;
3155+
3156+
WH_TEST_PRINT("AES test begin DEVID=0x%X\n", devId);
31313157

31323158
memset(plainIn, 0xAA, sizeof(plainIn));
31333159

@@ -3370,6 +3396,7 @@ static int whTestCrypto_Aes(whClientContext* ctx, int devId, WC_RNG* rng)
33703396

33713397
#ifdef HAVE_AES_ECB
33723398
if (ret == 0) {
3399+
WH_TEST_PRINT("AES ECB DEVID=0x%X: client-side begin\n", devId);
33733400
/* test aes ECB with client side key */
33743401
ret = wc_AesInit(aes, NULL, devId);
33753402
if (ret != 0) {
@@ -3415,45 +3442,55 @@ static int whTestCrypto_Aes(whClientContext* ctx, int devId, WC_RNG* rng)
34153442
}
34163443
}
34173444
if (ret == 0) {
3445+
WH_TEST_PRINT("AES ECB DEVID=0x%X: HSM-side begin\n", devId);
34183446
/* test aes ECB with HSM side key */
34193447
ret = wc_AesInit(aes, NULL, devId);
34203448
if (ret != 0) {
34213449
WH_ERROR_PRINT("Failed to wc_AesInit %d\n", ret);
34223450
}
34233451
else {
34243452
keyId = WH_KEYID_ERASED;
3453+
WH_TEST_PRINT("AES ECB DEVID=0x%X: key cache request\n", devId);
34253454
ret = wh_Client_KeyCache(
34263455
ctx, WH_NVM_FLAGS_USAGE_ENCRYPT | WH_NVM_FLAGS_USAGE_DECRYPT,
34273456
labelIn, sizeof(labelIn), key, sizeof(key), &keyId);
34283457
if (ret != 0) {
34293458
WH_ERROR_PRINT("Failed to wh_Client_KeyCache %d\n", ret);
34303459
}
34313460
else {
3461+
WH_TEST_PRINT("AES ECB DEVID=0x%X: key cache id=0x%X\n",
3462+
devId, keyId);
34323463
ret = wh_Client_AesSetKeyId(aes, keyId);
34333464
if (ret != 0) {
34343465
WH_ERROR_PRINT("Failed to wh_Client_SetKeyIdAes %d\n", ret);
34353466
}
34363467
else {
3468+
WH_TEST_PRINT("AES ECB DEVID=0x%X: set iv (null)\n", devId);
34373469
/* AES-ECB does not use IV */
34383470
ret = wc_AesSetIV(aes, NULL);
34393471
if (ret != 0) {
34403472
WH_ERROR_PRINT("Failed to wc_AesSetIV %d\n", ret);
34413473
}
34423474
else {
3475+
WH_TEST_PRINT("AES ECB DEVID=0x%X: encrypt\n", devId);
34433476
ret = wc_AesEcbEncrypt(aes, cipher, plainIn,
34443477
sizeof(plainIn));
34453478
if (ret != 0) {
34463479
WH_ERROR_PRINT("Failed to wc_AesEcbEncrypt %d\n",
34473480
ret);
34483481
}
34493482
else {
3483+
WH_TEST_PRINT("AES ECB DEVID=0x%X: reset iv (null)\n",
3484+
devId);
34503485
/* AES-ECB does not use IV */
34513486
ret = wc_AesSetIV(aes, NULL);
34523487
if (ret != 0) {
34533488
WH_ERROR_PRINT("Failed to wc_AesSetIV %d\n",
34543489
ret);
34553490
}
34563491
else {
3492+
WH_TEST_PRINT("AES ECB DEVID=0x%X: decrypt\n",
3493+
devId);
34573494
ret = wc_AesEcbDecrypt(aes, plainOut, cipher,
34583495
sizeof(plainIn));
34593496
if (ret != 0) {
@@ -3471,7 +3508,17 @@ static int whTestCrypto_Aes(whClientContext* ctx, int devId, WC_RNG* rng)
34713508
}
34723509
}
34733510
}
3474-
(void)wh_Client_KeyEvict(ctx, keyId);
3511+
evictRet = wh_Client_KeyEvict(ctx, keyId);
3512+
if (evictRet != WH_ERROR_OK) {
3513+
WH_ERROR_PRINT("AES ECB DEVID=0x%X: key evict failed %d\n",
3514+
devId, evictRet);
3515+
if (ret == WH_ERROR_OK) {
3516+
ret = evictRet;
3517+
}
3518+
}
3519+
else {
3520+
WH_TEST_PRINT("AES ECB DEVID=0x%X: key evicted\n", devId);
3521+
}
34753522
}
34763523
(void)wc_AesFree(aes);
34773524
memset(cipher, 0, sizeof(cipher));
@@ -5491,12 +5538,17 @@ int whTest_CryptoClientConfig(whClientConfig* config)
54915538

54925539
if (ret == 0) {
54935540
/* Test Key Cache functions */
5541+
WH_TEST_PRINT("Crypto stage: whTest_KeyCache begin\n");
54945542
ret = whTest_KeyCache(client, WH_DEV_ID, rng);
5543+
WH_TEST_PRINT("Crypto stage: whTest_KeyCache end ret=%d\n", ret);
54955544
}
54965545

54975546
if (ret == 0) {
54985547
/* Test Non-Exportable Flag enforcement on keystore */
5548+
WH_TEST_PRINT("Crypto stage: whTest_NonExportableKeystore begin\n");
54995549
ret = whTest_NonExportableKeystore(client, WH_DEV_ID, rng);
5550+
WH_TEST_PRINT("Crypto stage: whTest_NonExportableKeystore end ret=%d\n",
5551+
ret);
55005552
}
55015553

55025554
if (ret == 0) {

0 commit comments

Comments
 (0)