In rare situation when process could have malicious name
containing some tricky characters like whitespaces and numbers -
the parsing result may be wrong.
This patch fixes this issue by loading whole stat file into
memory and then proceed with parsing.
Change-Id: Iede6e0b6d1362a56449e1a53a0348f6cd7b4f768
+static int read_file(const char *filename, char *buf, size_t buf_size)
+{
+ FILE *fp = fopen(filename, "r");
+ if (!fp) return -1;
+
+ size_t read = fread(buf, 1, buf_size, fp);
+ if (read <= 0) {
+ fclose(fp);
+ return -1;
+ }
+ buf[read-1] = '\0';
+ fclose(fp);
+ return read;
+}
+
int procfs_read_process_stat(int pid, struct procfs_process_stat *usage)
{
ON_NULL_RETURN_VAL(usage, -1);
ON_TRUE_RETURN_VAL(pid <= 0, -1);
char statpath[64];
int procfs_read_process_stat(int pid, struct procfs_process_stat *usage)
{
ON_NULL_RETURN_VAL(usage, -1);
ON_TRUE_RETURN_VAL(pid <= 0, -1);
char statpath[64];
unsigned long long utime, stime;
unsigned long rss;
unsigned long long utime, stime;
unsigned long rss;
snprintf(statpath, sizeof(statpath), PIDSTAT_FILEPATH, pid);
snprintf(statpath, sizeof(statpath), PIDSTAT_FILEPATH, pid);
- FILE *stat_fp = fopen(statpath, "r");
- if (!stat_fp) {
- ERR("failed to open %s", statpath);
+ if ((read = read_file(statpath, buf, sizeof(buf))) <= 0) {
- if (fscanf(stat_fp, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s") < 0) {
- ERR("reading pid stat file failed");
- fclose(stat_fp);
+ if (read == sizeof(buf)) {
- if (fscanf(stat_fp, "%llu %llu", &utime, &stime) != 2) {
+ char *name_end = strrchr(buf, ')');
+ if (!name_end) return -1;
+
+ name_end += 1;
+
+ if (sscanf(name_end,
+ "%*c "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%llu "
+ "%llu "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%*s "
+ "%ld"
+ , &utime, &stime, &rss) != 3) {
ERR("reading pid stat file failed");
ERR("reading pid stat file failed");
- fclose(stat_fp);
- return -1;
- }
-
- if (fscanf(stat_fp, "%*s %*s %*s %*s %*s %*s %*s %*s") < 0) {
- ERR("reading pid stat file failed");
- fclose(stat_fp);
- return -1;
- }
-
- if (fscanf(stat_fp, "%ld", &rss) != 1) {
- ERR("reading pid stat file failed");
- fclose(stat_fp);
usage->stime = stime;
usage->rss = rss;
usage->stime = stime;
usage->rss = rss;