Subject: [PATCH] [BZ 151416] mon_fsstatd: fix double free in error path and skip virtual fs From: Gerald Schaefer Description: mon_fsstatd: fix double free in error path and skip virtual fs Symptom: The daemon is stopped and the following messages can be found in syslog: "statvfs error on /run/user/0: Permission denied" and "double free or corruption (!prev)". Problem: The error handling code for a failing statvfs() call erroneously does an extra fclose(), conflicting with the later fclose(). Also, breaking out of the inner loop at this point doesn't make sense, because there may be other mounted filesystems that would be skipped. The reason for the failing statvfs() (on /run/user/0) is a wrong selinux context (when started via systemctl), and this error will spam the syslog if we only fix the double free. Since /run/user/0 is a tmpfs, and mon_fsstatd is supposed to collect only physical filesystem data, it is wrong to even try to access /run/user/0. Solution: Remove the extra fclose(), replace the break with a continue, and add tmpfs (and others) to the list of ignored virtual filesystems. Reproduction: Start mon_fsstatd via service/systemctl. Upstream-ID: - Problem-ID: 151416 Signed-off-by: Gerald Schaefer --- mon_tools/mon_fsstatd.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) --- a/mon_tools/mon_fsstatd.c +++ b/mon_tools/mon_fsstatd.c @@ -323,16 +323,31 @@ static int fsstatd_do_work(void) strncmp(ent->mnt_type, "none", 4) == 0 || strncmp(ent->mnt_type, "proc", 4) == 0 || strncmp(ent->mnt_type, "subfs", 5) == 0 || + strncmp(ent->mnt_type, "nfsd", 4) == 0 || + strncmp(ent->mnt_type, "tmpfs", 5) == 0 || + strncmp(ent->mnt_type, "sysfs", 5) == 0 || + strncmp(ent->mnt_type, "pstore", 6) == 0 || + strncmp(ent->mnt_type, "cgroup", 6) == 0 || + strncmp(ent->mnt_type, "mqueue", 6) == 0 || + strncmp(ent->mnt_type, "devpts", 6) == 0 || + strncmp(ent->mnt_type, "debugfs", 7) == 0 || + strncmp(ent->mnt_type, "devtmpfs", 8) == 0 || + strncmp(ent->mnt_type, "configfs", 8) == 0 || + strncmp(ent->mnt_type, "selinuxfs", 9) == 0 || + strncmp(ent->mnt_type, "hugetlbfs", 9) == 0 || + strncmp(ent->mnt_type, "securityfs", 10) == 0 || + strncmp(ent->mnt_type, "rpc_pipefs", 10) == 0 || + strncmp(ent->mnt_type, "binfmt_misc", 11) == 0 || strncmp(ent->mnt_type, "ignore", 6) == 0)) { ent = getmntent(mnttab); continue; } result = statvfs(ent->mnt_dir, &buf); if (result != 0) { - fclose(mnttab); syslog(LOG_ERR, "statvfs error on %s: %s\n", ent->mnt_dir, strerror(errno)); - break; + ent = getmntent(mnttab); + continue; } if (buf.f_blocks > 0)