Date: Wed, 15 Apr 2015 09:13:11 +0000 (UTC) From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r281551 - in head/sys: compat/freebsd32 compat/linprocfs kern sys Message-ID: <201504150913.t3F9DBxe052815@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201504150913.t3F9DBxe052815>