Skip to content

Commit

Permalink
FreeBSD: Fix leaked strings in libspl mnttab
Browse files Browse the repository at this point in the history
The FreeBSD implementations of various libspl functions for getting
mounted device informantion were found to leak several strings which
were being allocated in statfs2mnttab but never freed.

The Solaris getmntany(3C) and related interfaces are expected to return
strings residing in static buffers that need to be copied rather than
freed by the caller.

Use static thread-local storage to stash the mnttab structure strings
from FreeBSD's statfs info rather than strings allocated on the heap by
strdup(3).

While here, remove some stray commented out lines.

Signed-off-by: Ryan Moeller <[email protected]>
  • Loading branch information
Ryan Moeller authored and Ryan Moeller committed Jan 11, 2022
1 parent d6c1bbd commit 9cae5d7
Showing 1 changed file with 44 additions and 38 deletions.
82 changes: 44 additions & 38 deletions lib/libspl/os/freebsd/mnttab.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,42 +91,6 @@ optadd(char *mntopts, size_t size, const char *opt)
strlcat(mntopts, opt, size);
}

void
statfs2mnttab(struct statfs *sfs, struct mnttab *mp)
{
static char mntopts[MNTMAXSTR];
long flags;

mntopts[0] = '\0';

flags = sfs->f_flags;
#define OPTADD(opt) optadd(mntopts, sizeof (mntopts), (opt))
if (flags & MNT_RDONLY)
OPTADD(MNTOPT_RO);
else
OPTADD(MNTOPT_RW);
if (flags & MNT_NOSUID)
OPTADD(MNTOPT_NOSETUID);
else
OPTADD(MNTOPT_SETUID);
if (flags & MNT_UPDATE)
OPTADD(MNTOPT_REMOUNT);
if (flags & MNT_NOATIME)
OPTADD(MNTOPT_NOATIME);
else
OPTADD(MNTOPT_ATIME);
OPTADD(MNTOPT_NOXATTR);
if (flags & MNT_NOEXEC)
OPTADD(MNTOPT_NOEXEC);
else
OPTADD(MNTOPT_EXEC);
#undef OPTADD
mp->mnt_special = strdup(sfs->f_mntfromname);
mp->mnt_mountp = strdup(sfs->f_mntonname);
mp->mnt_fstype = strdup(sfs->f_fstypename);
mp->mnt_mntopts = strdup(mntopts);
}

static struct statfs *gsfs = NULL;
static int allfs = 0;

Expand Down Expand Up @@ -163,10 +127,53 @@ statfs_init(void)
return (error);
}

#define BUFSIZE (sizeof (gsfs->f_fstypename) + sizeof (gsfs->f_mntfromname) + \
sizeof(gsfs->f_mntonname) + MNTMAXSTR)

static __thread char buf[BUFSIZE];

void
statfs2mnttab(struct statfs *sfs, struct mnttab *mp)
{
static char mntopts[MNTMAXSTR];
long flags;

mntopts[0] = '\0';

flags = sfs->f_flags;
#define OPTADD(opt) optadd(mntopts, sizeof (mntopts), (opt))
if (flags & MNT_RDONLY)
OPTADD(MNTOPT_RO);
else
OPTADD(MNTOPT_RW);
if (flags & MNT_NOSUID)
OPTADD(MNTOPT_NOSETUID);
else
OPTADD(MNTOPT_SETUID);
if (flags & MNT_UPDATE)
OPTADD(MNTOPT_REMOUNT);
if (flags & MNT_NOATIME)
OPTADD(MNTOPT_NOATIME);
else
OPTADD(MNTOPT_ATIME);
OPTADD(MNTOPT_NOXATTR);
if (flags & MNT_NOEXEC)
OPTADD(MNTOPT_NOEXEC);
else
OPTADD(MNTOPT_EXEC);
#undef OPTADD
char *p = buf, *e = buf + BUFSIZE;
#define STASH(d, s) p += 1 + strlcpy((d = p), s, e - p)
STASH(mp->mnt_special, sfs->f_mntfromname);
STASH(mp->mnt_mountp, sfs->f_mntonname);
STASH(mp->mnt_fstype, sfs->f_fstypename);
STASH(mp->mnt_mntopts, mntopts);
#undef STASH
}

int
getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
{
// struct statfs *sfs;
int i, error;

error = statfs_init();
Expand Down Expand Up @@ -195,7 +202,6 @@ getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
int
getmntent(FILE *fp, struct mnttab *mp)
{
// struct statfs *sfs;
int error, nfs;

nfs = (int)lseek(fileno(fp), 0, SEEK_CUR);
Expand Down

0 comments on commit 9cae5d7

Please sign in to comment.