[perfmon2] [PATCH] Check for possible truncation by snprintf
Status: Beta
Brought to you by:
seranian
|
From: William C. <wc...@re...> - 2018-01-30 21:17:14
|
Fedora rawhide (fc28) has compiler flags set to check for possible
truncations by snprintf. If the return value of snprintf is not
checked, gcc estimates the maximum size possible based on the arrays
and the format string. This can be a bit pessimistic. Added code to
check the value returned by snprintf to more accurately determine when
truncation occurs at runtime.
---
lib/pfmlib_perf_event_pmu.c | 16 +++++++++++++---
perf_examples/syst_count.c | 6 ++++--
perf_examples/syst_smpl.c | 6 ++++--
3 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/lib/pfmlib_perf_event_pmu.c b/lib/pfmlib_perf_event_pmu.c
index 86ff824..ca371d8 100644
--- a/lib/pfmlib_perf_event_pmu.c
+++ b/lib/pfmlib_perf_event_pmu.c
@@ -344,6 +344,7 @@ gen_tracepoint_table(void)
err = 0;
while((d1 = readdir(dir1)) && err >= 0) {
+ int retlen;
if (!strcmp(d1->d_name, "."))
continue;
@@ -351,7 +352,10 @@ gen_tracepoint_table(void)
if (!strcmp(d1->d_name, ".."))
continue;
- snprintf(d2path, MAXPATHLEN, "%s/%s", debugfs_mnt, d1->d_name);
+ retlen = snprintf(d2path, MAXPATHLEN, "%s/%s", debugfs_mnt, d1->d_name);
+ /* if string truncated do not try to open the corrupted path */
+ if (retlen < 0 || retlen >= MAXPATHLEN)
+ continue;
/* fails if d2path is not a directory */
dir2 = opendir(d2path);
@@ -398,10 +402,16 @@ gen_tracepoint_table(void)
continue;
#ifdef HAS_OPENAT
- snprintf(idpath, MAXPATHLEN, "%s/id", d2->d_name);
+ retlen = snprintf(idpath, MAXPATHLEN, "%s/id", d2->d_name);
+ /* if string truncated do not try to open the corrupted path */
+ if (retlen < 0 || retlen >= MAXPATHLEN)
+ continue;
fd = openat(dir2_fd, idpath, O_RDONLY);
#else
- snprintf(idpath, MAXPATHLEN, "%s/%s/id", d2path, d2->d_name);
+ retlen = snprintf(idpath, MAXPATHLEN, "%s/%s/id", d2path, d2->d_name);
+ /* if string truncated do not try to open the corrupted path */
+ if (retlen < 0 || retlen >= MAXPATHLEN)
+ continue;
fd = open(idpath, O_RDONLY);
#endif
if (fd == -1)
diff --git a/perf_examples/syst_count.c b/perf_examples/syst_count.c
index e0fa42e..7841d01 100644
--- a/perf_examples/syst_count.c
+++ b/perf_examples/syst_count.c
@@ -112,12 +112,14 @@ open_cgroup(char *name)
{
char path[MAX_PATH+1];
char mnt[MAX_PATH+1];
- int cfd;
+ int cfd, retlen;
if (cgroupfs_find_mountpoint(mnt, MAX_PATH+1))
errx(1, "cannot find cgroup fs mount point");
- snprintf(path, MAX_PATH, "%s/%s", mnt, name);
+ retlen = snprintf(path, MAX_PATH, "%s/%s", mnt, name);
+ if (retlen < 0 || retlen >= MAX_PATH)
+ warn("path truncated %s/%s\n", mnt, name);
cfd = open(path, O_RDONLY);
if (cfd == -1)
diff --git a/perf_examples/syst_smpl.c b/perf_examples/syst_smpl.c
index 6b70e0e..a8b00df 100755
--- a/perf_examples/syst_smpl.c
+++ b/perf_examples/syst_smpl.c
@@ -278,12 +278,14 @@ open_cgroup(char *name)
{
char path[MAX_PATH+1];
char mnt[MAX_PATH+1];
- int cfd;
+ int cfd, retlen;
if (cgroupfs_find_mountpoint(mnt, MAX_PATH+1))
errx(1, "cannot find cgroup fs mount point");
- snprintf(path, MAX_PATH, "%s/%s", mnt, name);
+ retlen = snprintf(path, MAX_PATH, "%s/%s", mnt, name);
+ if (retlen < 0 || retlen >= MAX_PATH)
+ warn("path truncated %s/%s\n", mnt, name);
cfd = open(path, O_RDONLY);
if (cfd == -1)
--
2.14.3
|