svn commit: r281551 - in head/sys: compat/freebsd32 compat/linprocfs kern sys
Edward Tomasz Napierala
trasz at FreeBSD.org
Wed Apr 15 09:13:13 UTC 2015
Author: trasz
Date: Wed Apr 15 09:13:11 2015
New Revision: 281551
URL: https://svnweb.freebsd.org/changeset/base/281551
Log:
Rewrite linprocfs_domtab() as a wrapper around kern_getfsstat(). This
adds missing jail and MAC checks.
Differential Revision: https://reviews.freebsd.org/D2193
Reviewed by: kib@
MFC after: 1 month
Sponsored by: The FreeBSD Foundation
Modified:
head/sys/compat/freebsd32/freebsd32_misc.c
head/sys/compat/linprocfs/linprocfs.c
head/sys/kern/vfs_syscalls.c
head/sys/sys/syscallsubr.h
Modified: head/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_misc.c Wed Apr 15 09:09:20 2015 (r281550)
+++ head/sys/compat/freebsd32/freebsd32_misc.c Wed Apr 15 09:13:11 2015 (r281551)
@@ -253,9 +253,8 @@ freebsd4_freebsd32_getfsstat(struct thre
count = uap->bufsize / sizeof(struct statfs32);
size = count * sizeof(struct statfs);
- error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags);
+ error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE, uap->flags);
if (size > 0) {
- count = td->td_retval[0];
sp = buf;
while (count > 0 && error == 0) {
copy_statfs(sp, &stat32);
@@ -266,6 +265,8 @@ freebsd4_freebsd32_getfsstat(struct thre
}
free(buf, M_TEMP);
}
+ if (error == 0)
+ td->td_retval[0] = count;
return (error);
}
#endif
Modified: head/sys/compat/linprocfs/linprocfs.c
==============================================================================
--- head/sys/compat/linprocfs/linprocfs.c Wed Apr 15 09:09:20 2015 (r281550)
+++ head/sys/compat/linprocfs/linprocfs.c Wed Apr 15 09:13:11 2015 (r281551)
@@ -53,10 +53,10 @@ __FBSDID("$FreeBSD$");
#include <sys/filedesc.h>
#include <sys/jail.h>
#include <sys/kernel.h>
+#include <sys/limits.h>
#include <sys/linker.h>
#include <sys/lock.h>
#include <sys/malloc.h>
-#include <sys/mount.h>
#include <sys/msg.h>
#include <sys/mutex.h>
#include <sys/namei.h>
@@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sem.h>
#include <sys/smp.h>
#include <sys/socket.h>
+#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/time.h>
@@ -326,11 +327,12 @@ static int
linprocfs_domtab(PFS_FILL_ARGS)
{
struct nameidata nd;
- struct mount *mp;
const char *lep;
char *dlep, *flep, *mntto, *mntfrom, *fstype;
size_t lep_len;
int error;
+ struct statfs *buf, *sp;
+ size_t count;
/* resolve symlinks etc. in the emulation tree prefix */
NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, linux_emul_path, td);
@@ -344,20 +346,26 @@ linprocfs_domtab(PFS_FILL_ARGS)
}
lep_len = strlen(lep);
- mtx_lock(&mountlist_mtx);
- error = 0;
- TAILQ_FOREACH(mp, &mountlist, mnt_list) {
+ buf = NULL;
+ error = kern_getfsstat(td, &buf, SIZE_T_MAX, &count,
+ UIO_SYSSPACE, MNT_WAIT);
+ if (error != 0) {
+ free(buf, M_TEMP);
+ free(flep, M_TEMP);
+ return (error);
+ }
+
+ for (sp = buf; count > 0; sp++, count--) {
/* determine device name */
- mntfrom = mp->mnt_stat.f_mntfromname;
+ mntfrom = sp->f_mntfromname;
/* determine mount point */
- mntto = mp->mnt_stat.f_mntonname;
- if (strncmp(mntto, lep, lep_len) == 0 &&
- mntto[lep_len] == '/')
+ mntto = sp->f_mntonname;
+ if (strncmp(mntto, lep, lep_len) == 0 && mntto[lep_len] == '/')
mntto += lep_len;
/* determine fs type */
- fstype = mp->mnt_stat.f_fstypename;
+ fstype = sp->f_fstypename;
if (strcmp(fstype, pn->pn_info->pi_name) == 0)
mntfrom = fstype = "proc";
else if (strcmp(fstype, "procfs") == 0)
@@ -365,16 +373,16 @@ linprocfs_domtab(PFS_FILL_ARGS)
if (strcmp(fstype, "linsysfs") == 0) {
sbuf_printf(sb, "/sys %s sysfs %s", mntto,
- mp->mnt_stat.f_flags & MNT_RDONLY ? "ro" : "rw");
+ sp->f_flags & MNT_RDONLY ? "ro" : "rw");
} else {
/* For Linux msdosfs is called vfat */
if (strcmp(fstype, "msdosfs") == 0)
fstype = "vfat";
sbuf_printf(sb, "%s %s %s %s", mntfrom, mntto, fstype,
- mp->mnt_stat.f_flags & MNT_RDONLY ? "ro" : "rw");
+ sp->f_flags & MNT_RDONLY ? "ro" : "rw");
}
#define ADD_OPTION(opt, name) \
- if (mp->mnt_stat.f_flags & (opt)) sbuf_printf(sb, "," name);
+ if (sp->f_flags & (opt)) sbuf_printf(sb, "," name);
ADD_OPTION(MNT_SYNCHRONOUS, "sync");
ADD_OPTION(MNT_NOEXEC, "noexec");
ADD_OPTION(MNT_NOSUID, "nosuid");
@@ -387,7 +395,8 @@ linprocfs_domtab(PFS_FILL_ARGS)
/* a real Linux mtab will also show NFS options */
sbuf_printf(sb, " 0 0\n");
}
- mtx_unlock(&mountlist_mtx);
+
+ free(buf, M_TEMP);
free(flep, M_TEMP);
return (error);
}
Modified: head/sys/kern/vfs_syscalls.c
==============================================================================
--- head/sys/kern/vfs_syscalls.c Wed Apr 15 09:09:20 2015 (r281550)
+++ head/sys/kern/vfs_syscalls.c Wed Apr 15 09:13:11 2015 (r281551)
@@ -434,9 +434,14 @@ sys_getfsstat(td, uap)
int flags;
} */ *uap;
{
+ size_t count;
+ int error;
- return (kern_getfsstat(td, &uap->buf, uap->bufsize, UIO_USERSPACE,
- uap->flags));
+ error = kern_getfsstat(td, &uap->buf, uap->bufsize, &count,
+ UIO_USERSPACE, uap->flags);
+ if (error == 0)
+ td->td_retval[0] = count;
+ return (error);
}
/*
@@ -446,7 +451,7 @@ sys_getfsstat(td, uap)
*/
int
kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
- enum uio_seg bufseg, int flags)
+ size_t *countp, enum uio_seg bufseg, int flags)
{
struct mount *mp, *nmp;
struct statfs *sfsp, *sp, sb;
@@ -533,9 +538,9 @@ kern_getfsstat(struct thread *td, struct
}
mtx_unlock(&mountlist_mtx);
if (sfsp && count > maxcount)
- td->td_retval[0] = maxcount;
+ *countp = maxcount;
else
- td->td_retval[0] = count;
+ *countp = count;
return (0);
}
@@ -624,9 +629,9 @@ freebsd4_getfsstat(td, uap)
count = uap->bufsize / sizeof(struct ostatfs);
size = count * sizeof(struct statfs);
- error = kern_getfsstat(td, &buf, size, UIO_SYSSPACE, uap->flags);
+ error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE,
+ uap->flags);
if (size > 0) {
- count = td->td_retval[0];
sp = buf;
while (count > 0 && error == 0) {
cvtstatfs(sp, &osb);
@@ -637,6 +642,8 @@ freebsd4_getfsstat(td, uap)
}
free(buf, M_TEMP);
}
+ if (error == 0)
+ td->td_retval[0] = count;
return (error);
}
Modified: head/sys/sys/syscallsubr.h
==============================================================================
--- head/sys/sys/syscallsubr.h Wed Apr 15 09:09:20 2015 (r281550)
+++ head/sys/sys/syscallsubr.h Wed Apr 15 09:13:11 2015 (r281551)
@@ -104,7 +104,7 @@ int kern_futimens(struct thread *td, int
int kern_getdirentries(struct thread *td, int fd, char *buf, u_int count,
long *basep, ssize_t *residp, enum uio_seg bufseg);
int kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
- enum uio_seg bufseg, int flags);
+ size_t *countp, enum uio_seg bufseg, int flags);
int kern_getitimer(struct thread *, u_int, struct itimerval *);
int kern_getppid(struct thread *);
int kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
More information about the svn-src-head
mailing list