Harden the extraction of boot time for the Linux platform

There is a possible path - albeit theoretical really - through
the btime initialization code in Linux ProcessList_new(), when
String_startsWith() is always false, which can result in btime
not being initialized.

This commit refactors the code to remove that possibility.
This commit is contained in:
Nathan Scott 2020-12-14 12:16:32 +11:00
parent a3db2da4a7
commit b7836515e8
1 changed files with 11 additions and 12 deletions

View File

@ -226,26 +226,25 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidMatchList, ui
// Test /proc/PID/smaps_rollup availability (faster to parse, Linux 4.14+) // Test /proc/PID/smaps_rollup availability (faster to parse, Linux 4.14+)
this->haveSmapsRollup = (access(PROCDIR "/self/smaps_rollup", R_OK) == 0); this->haveSmapsRollup = (access(PROCDIR "/self/smaps_rollup", R_OK) == 0);
// Read btime // Read btime (the kernel boot time, as number of seconds since the epoch)
{ {
FILE* statfile = fopen(PROCSTATFILE, "r"); FILE* statfile = fopen(PROCSTATFILE, "r");
if (statfile == NULL) { if (statfile == NULL)
CRT_fatalError("Cannot open " PROCSTATFILE); CRT_fatalError("Cannot open " PROCSTATFILE);
}
while (true) { while (true) {
char buffer[PROC_LINE_LENGTH + 1]; char buffer[PROC_LINE_LENGTH + 1];
if (fgets(buffer, sizeof(buffer), statfile) == NULL) { if (fgets(buffer, sizeof(buffer), statfile) == NULL)
CRT_fatalError("No btime in " PROCSTATFILE); break;
} else if (String_startsWith(buffer, "btime ")) { if (String_startsWith(buffer, "btime ") == false)
if (sscanf(buffer, "btime %lld\n", &btime) != 1) { continue;
if (sscanf(buffer, "btime %lld\n", &btime) == 1)
break;
CRT_fatalError("Failed to parse btime from " PROCSTATFILE); CRT_fatalError("Failed to parse btime from " PROCSTATFILE);
} }
break;
}
}
fclose(statfile); fclose(statfile);
if (!btime)
CRT_fatalError("No btime in " PROCSTATFILE);
} }
// Initialize CPU count // Initialize CPU count