Skip to content

Commit fd02c4f

Browse files
committed
Fixes for copilot reviews
1 parent 082c0f9 commit fd02c4f

File tree

6 files changed

+71
-27
lines changed

6 files changed

+71
-27
lines changed

src/fwtpm/fwtpm_io.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,22 @@
5353

5454
#include <wolftpm/tpm2_socket.h>
5555

56+
#include <signal.h> /* sig_atomic_t */
5657
#ifndef _WIN32
5758
#include <sys/select.h>
5859
#include <arpa/inet.h>
59-
#include <signal.h>
6060
#endif
6161

62+
/* Async-signal-safe stop flag. Set by FWTPM_IO_RequestStop() (callable from
63+
* a signal handler) and polled by the server loop. Using sig_atomic_t guarantees
64+
* POSIX-conformant atomic read/write from inside a signal handler. */
65+
static volatile sig_atomic_t g_stopRequested = 0;
66+
67+
void FWTPM_IO_RequestStop(void)
68+
{
69+
g_stopRequested = 1;
70+
}
71+
6272
/* Use TPM2_Packet_SwapU32 from tpm2_packet.c (compiled directly) */
6373
#define FwTpmSwapU32 TPM2_Packet_SwapU32
6474

@@ -553,6 +563,12 @@ int FWTPM_IO_ServerLoop(FWTPM_CTX* ctx)
553563
* the command connection open while sending POWER_ON on the platform port.
554564
* A sequential accept/handle loop would deadlock here. */
555565
while (ctx->running) {
566+
/* Propagate async stop request into ctx state from normal
567+
* control flow (signal handler only sets the volatile flag). */
568+
if (g_stopRequested) {
569+
ctx->running = 0;
570+
break;
571+
}
556572
FD_ZERO(&readFds);
557573
FD_SET(ctx->io.listenFd, &readFds);
558574
FD_SET(ctx->io.platListenFd, &readFds);

src/fwtpm/fwtpm_main.c

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,13 @@
3838
#include <string.h>
3939
#include <signal.h>
4040

41-
/* Global context pointer for signal handler.
42-
* Only the volatile flag is set in the handler; actual cleanup
43-
* happens in the main loop after the flag is observed. */
44-
static volatile sig_atomic_t g_terminate = 0;
45-
static FWTPM_CTX* g_ctx = NULL;
46-
41+
/* Signal handler does only async-signal-safe work: it calls
42+
* FWTPM_IO_RequestStop(), which sets a volatile sig_atomic_t. The server
43+
* loop polls that flag and clears ctx->running from normal control flow. */
4744
static void sigterm_handler(int sig)
4845
{
4946
(void)sig;
50-
g_terminate = 1;
51-
if (g_ctx != NULL) {
52-
g_ctx->running = 0;
53-
}
47+
FWTPM_IO_RequestStop();
5448
}
5549

5650
static void usage(const char* progname)
@@ -159,7 +153,6 @@ int main(int argc, char* argv[])
159153
printf(" Model: %s\n", FWTPM_MODEL);
160154

161155
/* Install signal handler for graceful shutdown with NV save */
162-
g_ctx = &ctx;
163156
sa.sa_handler = sigterm_handler;
164157
sigemptyset(&sa.sa_mask);
165158
sa.sa_flags = 0;

src/tpm2_swtpm.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,19 @@
5858
#include <netinet/in.h>
5959
#include <arpa/inet.h>
6060
#endif
61-
#ifndef NO_GETENV
62-
#include <stdlib.h>
61+
#if !defined(NO_GETENV) || defined(WOLFTPM_SWTPM_UART)
62+
#include <stdlib.h> /* getenv / atoi */
6363
#endif
6464
#ifdef WOLFTPM_SWTPM_UART
6565
#include <fcntl.h>
6666
#include <termios.h>
6767
#include <sys/stat.h>
68+
#ifndef O_CLOEXEC
69+
#define O_CLOEXEC 0
70+
#endif
71+
#ifndef O_NOFOLLOW
72+
#define O_NOFOLLOW 0
73+
#endif
6874
#endif
6975

7076
#include <wolftpm/tpm2_socket.h>
@@ -185,6 +191,13 @@ static TPM_RC SwTpmConnect(TPM2_CTX* ctx, const char* host, const char* port)
185191
#endif
186192
return TPM_RC_FAILURE;
187193
}
194+
/* If O_CLOEXEC wasn't available at compile time, set FD_CLOEXEC now. */
195+
if (O_CLOEXEC == 0) {
196+
int flags = fcntl(fd, F_GETFD);
197+
if (flags != -1) {
198+
(void)fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
199+
}
200+
}
188201
/* Verify the opened path is a character device */
189202
if (fstat(fd, &devStat) != 0 || !S_ISCHR(devStat.st_mode)) {
190203
close(fd);

tests/fwtpm_check.sh

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ wait_for_port() {
4444
return 1
4545
}
4646

47-
# Check if a port is in use (returns 0 if port is in use)
47+
# Check if a port is in use.
48+
# Returns: 0 = in use, 1 = free, 2 = unknown (no probe tool available)
4849
check_port_in_use() {
4950
local port="$1"
5051
if command -v nc >/dev/null 2>&1; then
@@ -53,22 +54,30 @@ check_port_in_use() {
5354
elif command -v ss >/dev/null 2>&1; then
5455
ss -tln 2>/dev/null | grep -q ":${port} "
5556
return $?
56-
elif netstat -tln 2>/dev/null | grep -q ":${port} "; then
57-
return 0
57+
elif command -v netstat >/dev/null 2>&1; then
58+
netstat -tln 2>/dev/null | grep -q ":${port} "
59+
return $?
5860
fi
59-
return 1 # no tool available, skip this port
61+
return 2 # no probe tool — cannot determine
6062
}
6163

6264
# Pick an available random port (returns port on stdout)
6365
pick_available_port() {
64-
local port attempts=0
66+
local port attempts=0 rv
6567
while [ $attempts -lt 20 ]; do
6668
if command -v shuf > /dev/null 2>&1; then
6769
port=$(shuf -i 10000-65000 -n 1)
6870
else
6971
port=$(( (RANDOM % 55000) + 10000 ))
7072
fi
71-
if ! check_port_in_use "$port"; then
73+
check_port_in_use "$port"; rv=$?
74+
if [ $rv -eq 1 ]; then
75+
echo "$port"
76+
return 0
77+
fi
78+
if [ $rv -eq 2 ]; then
79+
# No probe tool — accept the port; bind-time conflicts will surface
80+
# as a server startup error rather than silent flakiness.
7281
echo "$port"
7382
return 0
7483
fi
@@ -270,13 +279,21 @@ if [ $IS_FWTPM_MODE -eq 1 ]; then
270279
rm -f "$BUILD_DIR"/certs/tpm-*-cert.pem "$BUILD_DIR"/certs/tpm-*-cert.csr
271280
rm -f "$BUILD_DIR"/certs/server-*-cert.pem "$BUILD_DIR"/certs/client-*-cert.pem
272281

273-
# Clean up any stale PID files from prior crashed runs
282+
# Clean up any stale PID files from prior crashed runs.
283+
# Validate the process is actually fwtpm_server before killing —
284+
# PIDs can be reused, and signalling an unrelated process would
285+
# cause collateral damage.
274286
for stale_pid_file in /tmp/fwtpm_check_*.pid; do
275287
[ -f "$stale_pid_file" ] || continue
276288
stale_pid="$(cat "$stale_pid_file" 2>/dev/null)"
277289
if [ -n "$stale_pid" ] && kill -0 "$stale_pid" 2>/dev/null; then
278-
kill "$stale_pid" 2>/dev/null
279-
sleep 0.3
290+
stale_comm="$(ps -p "$stale_pid" -o comm= 2>/dev/null)"
291+
case "$stale_comm" in
292+
fwtpm_server|*fwtpm_server*)
293+
kill "$stale_pid" 2>/dev/null
294+
sleep 0.3
295+
;;
296+
esac
280297
fi
281298
rm -f "$stale_pid_file"
282299
done

tests/fwtpm_unit_tests.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ static int BuildCreatePrimaryCmd(byte* buf, TPM_ALG_ID algType)
895895
return pos;
896896
}
897897

898-
#ifndef NO_RSA
898+
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
899899
static void test_fwtpm_create_primary_rsa(void)
900900
{
901901
FWTPM_CTX ctx;
@@ -926,7 +926,7 @@ static void test_fwtpm_create_primary_rsa(void)
926926
FWTPM_Cleanup(&ctx);
927927
printf("Test fwTPM:\tCreatePrimary(RSA-2048):\t\tPassed\n");
928928
}
929-
#endif /* !NO_RSA */
929+
#endif /* !NO_RSA && WOLFSSL_KEY_GEN */
930930

931931
#ifdef HAVE_ECC
932932
static void test_fwtpm_create_primary_ecc(void)
@@ -1996,7 +1996,7 @@ int fwtpm_unit_tests(int argc, char *argv[])
19961996
test_fwtpm_clock_set();
19971997

19981998
/* Key operations */
1999-
#ifndef NO_RSA
1999+
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
20002000
test_fwtpm_create_primary_rsa();
20012001
#endif
20022002
#ifdef HAVE_ECC

wolftpm/fwtpm/fwtpm_io.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,14 @@ WOLFTPM_API int FWTPM_IO_Init(FWTPM_CTX* ctx);
5959
/* Cleanup sockets */
6060
WOLFTPM_API void FWTPM_IO_Cleanup(FWTPM_CTX* ctx);
6161

62-
/* Main server loop - blocks until ctx->running is cleared */
62+
/* Main server loop - blocks until ctx->running is cleared or stop requested */
6363
WOLFTPM_API int FWTPM_IO_ServerLoop(FWTPM_CTX* ctx);
6464

65+
/* Async-signal-safe: request the server loop to exit. Safe to call from
66+
* a signal handler — only sets a volatile sig_atomic_t flag that the
67+
* main loop polls. */
68+
WOLFTPM_API void FWTPM_IO_RequestStop(void);
69+
6570
#ifdef __cplusplus
6671
} /* extern "C" */
6772
#endif

0 commit comments

Comments
 (0)