Skip to content

Commit fcf210e

Browse files
committed
process start time verification to prevent PID reuse issues
1 parent 8a77680 commit fcf210e

4 files changed

Lines changed: 94 additions & 0 deletions

File tree

src/apps.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ typedef struct
5757
bool first_heartbeat; /**< Flag indicating whether the application has sent its first heartbeat. */
5858
int pid; /**< Process ID of the application. */
5959
time_t last_heartbeat; /**< Time when the last heartbeat was received from the application. */
60+
time_t start_time; /**< Process start time in clock ticks since system boot. */
6061
} Application_t;
6162

6263
typedef enum

src/process.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ bool process_is_running(int app_index)
4242
// Check if the application is running
4343
if(kill(pid, 0) == 0)
4444
{
45+
// Verify process identity by checking start time to prevent PID reuse issues
46+
time_t recorded_start_time = apps_get_array()[app_index].start_time;
47+
time_t current_start_time = get_process_start_time(pid);
48+
49+
if(current_start_time > 0 && recorded_start_time > 0 && current_start_time != recorded_start_time)
50+
{
51+
LOGE("Process %s PID %d has different start time (PID reused), treating as different process",
52+
get_app_name(app_index), pid);
53+
return false;
54+
}
55+
4556
return true; // Process is running
4657
}
4758
else if(errno == EPERM)
@@ -121,6 +132,8 @@ void process_start(int app_index)
121132
apps[app_index].started = true;
122133
apps[app_index].first_heartbeat = false;
123134
apps[app_index].pid = pid;
135+
// Record process start time from /proc/<pid>/stat
136+
apps[app_index].start_time = get_process_start_time(pid);
124137
LOGI("Process %s started (PID %d): %s", apps[app_index].name, apps[app_index].pid, apps[app_index].cmd);
125138
// Use heartbeat module to update heartbeat time
126139
heartbeat_update_time(app_index);
@@ -220,6 +233,7 @@ void process_kill(int app_index)
220233
apps[app_index].started = false;
221234
apps[app_index].first_heartbeat = false;
222235
apps[app_index].pid = 0;
236+
apps[app_index].start_time = 0;
223237
}
224238
else
225239
{

src/utils.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,77 @@ long get_uptime()
4747
return s_info.uptime;
4848
}
4949

50+
/**
51+
@brief Gets the process start time from /proc/<pid>/stat in clock ticks since boot.
52+
53+
According to proc(5), field 22 in /proc/<pid>/stat is the process start time
54+
in clock ticks since system boot.
55+
56+
@param pid Process ID to query.
57+
@return Process start time in clock ticks since boot, or 0 on error.
58+
*/
59+
time_t get_process_start_time(int pid)
60+
{
61+
char path[256];
62+
char buffer[1024];
63+
FILE *fp;
64+
long start_time = 0;
65+
66+
snprintf(path, sizeof(path), "/proc/%d/stat", pid);
67+
68+
fp = fopen(path, "r");
69+
if(fp == NULL)
70+
{
71+
return 0;
72+
}
73+
74+
if(fread(buffer, 1, sizeof(buffer) - 1, fp) <= 0)
75+
{
76+
fclose(fp);
77+
return 0;
78+
}
79+
fclose(fp);
80+
81+
buffer[sizeof(buffer) - 1] = '\0';
82+
83+
// Find the last ')' in the command name (field 2 is command in parentheses)
84+
// Then find field 22 (start time)
85+
char *ptr = strrchr(buffer, ')');
86+
if(ptr == NULL)
87+
{
88+
return 0;
89+
}
90+
91+
// Skip ')' and whitespace, then count 21 fields to get to field 22
92+
ptr++; // Skip ')'
93+
while(*ptr == ' ')
94+
{
95+
ptr++;
96+
}
97+
98+
// Count fields - skip first 21 fields
99+
int field = 1;
100+
while(field < 22 && *ptr != '\0')
101+
{
102+
while(*ptr == ' ')
103+
{
104+
ptr++;
105+
}
106+
while(*ptr != ' ' && *ptr != '\0')
107+
{
108+
ptr++;
109+
}
110+
field++;
111+
}
112+
113+
if(field == 22)
114+
{
115+
start_time = atol(ptr);
116+
}
117+
118+
return (time_t)start_time;
119+
}
120+
50121
void delay_ms(int ms)
51122
{
52123
if(ms > 1000)

src/utils.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ char *pstrcpy(char *s1, const char *s2);
9494
*/
9595
long get_uptime();
9696

97+
/**
98+
@brief Gets the process start time from /proc/<pid>/stat in clock ticks since boot.
99+
100+
@param pid Process ID to query.
101+
@return Process start time in clock ticks since boot, or 0 on error.
102+
*/
103+
time_t get_process_start_time(int pid);
104+
97105
/**
98106
@brief Waits for a specified number of milliseconds.
99107

0 commit comments

Comments
 (0)