X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/8f6c56a50524aa785f7e596d52dddfb331e18961..b226f5e54a60dc81db17b1260381d7dbfea3cdf1:/bsd/miscfs/devfs/devfs_vfsops.c?ds=sidebyside diff --git a/bsd/miscfs/devfs/devfs_vfsops.c b/bsd/miscfs/devfs/devfs_vfsops.c index c97601787..db3e249e9 100644 --- a/bsd/miscfs/devfs/devfs_vfsops.c +++ b/bsd/miscfs/devfs/devfs_vfsops.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2010 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -53,6 +53,12 @@ * devfs_vfsops.c * */ +/* + * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + */ /* * HISTORY * Dieter Siegmund (dieter@apple.com) Wed Jul 14 13:37:59 PDT 1999 @@ -69,15 +75,28 @@ #include #include #include +#include +#include +#include + +#if CONFIG_MACF +#include +#endif #include "devfs.h" #include "devfsdefs.h" -static int devfs_statfs( struct mount *mp, struct vfsstatfs *sbp, vfs_context_t context); -static int devfs_vfs_getattr(mount_t mp, struct vfs_attr *fsap, vfs_context_t context); +#if FDESC +#include "fdesc.h" +#endif /* FDESC */ + -static struct vfstable * devfs_vfsp = 0; +static int devfs_statfs( struct mount *mp, struct vfsstatfs *sbp, vfs_context_t ctx); +static int devfs_vfs_getattr(mount_t mp, struct vfs_attr *fsap, vfs_context_t ctx); +#if CONFIG_DEV_KMEM +extern boolean_t dev_kmem_enabled; +#endif /*- * Called from the generic VFS startups. @@ -88,26 +107,49 @@ static struct vfstable * devfs_vfsp = 0; * devices from devfs get sync'd. */ static int -devfs_init(struct vfsconf *vfsp) +devfs_init(__unused struct vfsconf *vfsp) { - devfs_vfsp = (struct vfstable *)vfsp; /* remember this for devfs_kernel_mount below */ - - if (devfs_sinit()) - return (ENOTSUP); - devfs_make_node(makedev(0, 0), DEVFS_CHAR, - UID_ROOT, GID_WHEEL, 0622, "console"); - devfs_make_node(makedev(2, 0), DEVFS_CHAR, - UID_ROOT, GID_WHEEL, 0666, "tty"); - devfs_make_node(makedev(3, 0), DEVFS_CHAR, - UID_ROOT, GID_KMEM, 0640, "mem"); - devfs_make_node(makedev(3, 1), DEVFS_CHAR, - UID_ROOT, GID_KMEM, 0640, "kmem"); - devfs_make_node(makedev(3, 2), DEVFS_CHAR, - UID_ROOT, GID_WHEEL, 0666, "null"); - devfs_make_node(makedev(3, 3), DEVFS_CHAR, - UID_ROOT, GID_WHEEL, 0666, "zero"); - devfs_make_node(makedev(6, 0), DEVFS_CHAR, - UID_ROOT, GID_WHEEL, 0600, "klog"); + if (devfs_sinit()) + return (ENOTSUP); + devfs_make_node(makedev(0, 0), DEVFS_CHAR, + UID_ROOT, GID_WHEEL, 0622, "console"); + devfs_make_node(makedev(2, 0), DEVFS_CHAR, + UID_ROOT, GID_WHEEL, 0666, "tty"); +#if CONFIG_DEV_KMEM + if (dev_kmem_enabled) { + /* (3,0) reserved for /dev/mem physical memory */ + devfs_make_node(makedev(3, 1), DEVFS_CHAR, + UID_ROOT, GID_KMEM, 0640, "kmem"); + } +#endif + devfs_make_node(makedev(3, 2), DEVFS_CHAR, + UID_ROOT, GID_WHEEL, 0666, "null"); + devfs_make_node(makedev(3, 3), DEVFS_CHAR, + UID_ROOT, GID_WHEEL, 0666, "zero"); + uint32_t logging_config = atm_get_diagnostic_config(); + + devfs_make_node(makedev(6, 0), DEVFS_CHAR, + UID_ROOT, GID_WHEEL, 0600, "klog"); + + if ( !(logging_config & ATM_TRACE_DISABLE) ) { + devfs_make_node(makedev(7, 0), DEVFS_CHAR, + UID_ROOT, GID_WHEEL, 0600, "oslog"); + if (cdevsw_setkqueueok(7, (&(cdevsw[7])), 0) == -1) { + return (ENOTSUP); + } + + devfs_make_node(makedev(8, 0), DEVFS_CHAR, + UID_ROOT, GID_WHEEL, 0600, "oslog_stream"); + if (cdevsw_setkqueueok(8, (&(cdevsw[8])), 0) == -1) { + return (ENOTSUP); + } + } + + +#if FDESC + devfs_fdesc_init(); +#endif + return 0; } @@ -126,7 +168,7 @@ devfs_init(struct vfsconf *vfsp) */ /*proto*/ int -devfs_mount(struct mount *mp, __unused vnode_t devvp, __unused user_addr_t data, vfs_context_t context) +devfs_mount(struct mount *mp, __unused vnode_t devvp, __unused user_addr_t data, vfs_context_t ctx) { struct devfsmount *devfs_mp_p; /* devfs specific mount info */ int error; @@ -158,8 +200,8 @@ devfs_mount(struct mount *mp, __unused vnode_t devvp, __unused user_addr_t data, /*- * Fill out some fields */ - mp->mnt_data = (qaddr_t)devfs_mp_p; - mp->mnt_vfsstat.f_fsid.val[0] = (int32_t)(void *)devfs_mp_p; + __IGNORE_WCASTALIGN(mp->mnt_data = (qaddr_t)devfs_mp_p); + mp->mnt_vfsstat.f_fsid.val[0] = (int32_t)(uintptr_t)devfs_mp_p; mp->mnt_vfsstat.f_fsid.val[1] = vfs_typenum(mp); mp->mnt_flag |= MNT_LOCAL; @@ -183,14 +225,14 @@ devfs_mount(struct mount *mp, __unused vnode_t devvp, __unused user_addr_t data, bzero(mp->mnt_vfsstat.f_mntfromname, MAXPATHLEN); bcopy("devfs",mp->mnt_vfsstat.f_mntfromname, 5); - (void)devfs_statfs(mp, &mp->mnt_vfsstat, context); + (void)devfs_statfs(mp, &mp->mnt_vfsstat, ctx); return 0; } static int -devfs_start(__unused struct mount *mp, __unused int flags, __unused vfs_context_t context) +devfs_start(__unused struct mount *mp, __unused int flags, __unused vfs_context_t ctx) { return 0; } @@ -199,7 +241,7 @@ devfs_start(__unused struct mount *mp, __unused int flags, __unused vfs_context_ * Unmount the filesystem described by mp. */ static int -devfs_unmount( struct mount *mp, int mntflags, __unused vfs_context_t context) +devfs_unmount( struct mount *mp, int mntflags, __unused vfs_context_t ctx) { struct devfsmount *devfs_mp_p = (struct devfsmount *)mp->mnt_data; int flags = 0; @@ -229,20 +271,21 @@ devfs_unmount( struct mount *mp, int mntflags, __unused vfs_context_t context) /* return the address of the root vnode in *vpp */ static int -devfs_root(struct mount *mp, struct vnode **vpp, vfs_context_t context) +devfs_root(struct mount *mp, struct vnode **vpp, __unused vfs_context_t ctx) { struct devfsmount *devfs_mp_p = (struct devfsmount *)(mp->mnt_data); int error; DEVFS_LOCK(); - error = devfs_dntovn(devfs_mp_p->plane_root->de_dnp, vpp, context->vc_proc); + /* last parameter to devfs_dntovn() is ignored */ + error = devfs_dntovn(devfs_mp_p->plane_root->de_dnp, vpp, NULL); DEVFS_UNLOCK(); return error; } static int -devfs_statfs( struct mount *mp, struct vfsstatfs *sbp, __unused vfs_context_t context) +devfs_statfs( struct mount *mp, struct vfsstatfs *sbp, __unused vfs_context_t ctx) { struct devfsmount *devfs_mp_p = (struct devfsmount *)mp->mnt_data; @@ -262,14 +305,14 @@ devfs_statfs( struct mount *mp, struct vfsstatfs *sbp, __unused vfs_context_t co sbp->f_bavail = 0; sbp->f_files = devfs_stats.nodes; sbp->f_ffree = 0; - sbp->f_fsid.val[0] = (int32_t)(void *)devfs_mp_p; + sbp->f_fsid.val[0] = (int32_t)(uintptr_t)devfs_mp_p; sbp->f_fsid.val[1] = vfs_typenum(mp); return 0; } static int -devfs_vfs_getattr(mount_t mp, struct vfs_attr *fsap, vfs_context_t context) +devfs_vfs_getattr(__unused mount_t mp, struct vfs_attr *fsap, __unused vfs_context_t ctx) { VFSATTR_RETURN(fsap, f_objcount, devfs_stats.nodes); VFSATTR_RETURN(fsap, f_maxobjcount, devfs_stats.nodes); @@ -291,18 +334,120 @@ devfs_vfs_getattr(mount_t mp, struct vfs_attr *fsap, vfs_context_t context) VFSATTR_RETURN(fsap, f_ffree, 0); VFSATTR_RETURN(fsap, f_fssubtype, 0); + if (VFSATTR_IS_ACTIVE(fsap, f_capabilities)) { + fsap->f_capabilities.capabilities[VOL_CAPABILITIES_FORMAT] = + VOL_CAP_FMT_SYMBOLICLINKS | + VOL_CAP_FMT_HARDLINKS | + VOL_CAP_FMT_NO_ROOT_TIMES | + VOL_CAP_FMT_CASE_SENSITIVE | + VOL_CAP_FMT_CASE_PRESERVING | + VOL_CAP_FMT_FAST_STATFS | + VOL_CAP_FMT_2TB_FILESIZE | + VOL_CAP_FMT_HIDDEN_FILES; + fsap->f_capabilities.capabilities[VOL_CAPABILITIES_INTERFACES] = + VOL_CAP_INT_ATTRLIST ; + fsap->f_capabilities.capabilities[VOL_CAPABILITIES_RESERVED1] = 0; + fsap->f_capabilities.capabilities[VOL_CAPABILITIES_RESERVED2] = 0; + + fsap->f_capabilities.valid[VOL_CAPABILITIES_FORMAT] = + VOL_CAP_FMT_PERSISTENTOBJECTIDS | + VOL_CAP_FMT_SYMBOLICLINKS | + VOL_CAP_FMT_HARDLINKS | + VOL_CAP_FMT_JOURNAL | + VOL_CAP_FMT_JOURNAL_ACTIVE | + VOL_CAP_FMT_NO_ROOT_TIMES | + VOL_CAP_FMT_SPARSE_FILES | + VOL_CAP_FMT_ZERO_RUNS | + VOL_CAP_FMT_CASE_SENSITIVE | + VOL_CAP_FMT_CASE_PRESERVING | + VOL_CAP_FMT_FAST_STATFS | + VOL_CAP_FMT_2TB_FILESIZE | + VOL_CAP_FMT_OPENDENYMODES | + VOL_CAP_FMT_HIDDEN_FILES | + VOL_CAP_FMT_PATH_FROM_ID | + VOL_CAP_FMT_NO_VOLUME_SIZES; + fsap->f_capabilities.valid[VOL_CAPABILITIES_INTERFACES] = + VOL_CAP_INT_SEARCHFS | + VOL_CAP_INT_ATTRLIST | + VOL_CAP_INT_NFSEXPORT | + VOL_CAP_INT_READDIRATTR | + VOL_CAP_INT_EXCHANGEDATA | + VOL_CAP_INT_COPYFILE | + VOL_CAP_INT_ALLOCATE | + VOL_CAP_INT_VOL_RENAME | + VOL_CAP_INT_ADVLOCK | + VOL_CAP_INT_FLOCK | + VOL_CAP_INT_EXTENDED_SECURITY | + VOL_CAP_INT_USERACCESS | + VOL_CAP_INT_MANLOCK | + VOL_CAP_INT_EXTENDED_ATTR | + VOL_CAP_INT_NAMEDSTREAMS; + fsap->f_capabilities.valid[VOL_CAPABILITIES_RESERVED1] = 0; + fsap->f_capabilities.valid[VOL_CAPABILITIES_RESERVED2] = 0; + + VFSATTR_SET_SUPPORTED(fsap, f_capabilities); + } + + if (VFSATTR_IS_ACTIVE(fsap, f_attributes)) { + fsap->f_attributes.validattr.commonattr = + ATTR_CMN_NAME | ATTR_CMN_DEVID | ATTR_CMN_FSID | + ATTR_CMN_OBJTYPE | ATTR_CMN_OBJTAG | ATTR_CMN_OBJID | + ATTR_CMN_PAROBJID | + ATTR_CMN_MODTIME | ATTR_CMN_CHGTIME | ATTR_CMN_ACCTIME | + ATTR_CMN_OWNERID | ATTR_CMN_GRPID | ATTR_CMN_ACCESSMASK | + ATTR_CMN_FLAGS | ATTR_CMN_USERACCESS | ATTR_CMN_FILEID; + fsap->f_attributes.validattr.volattr = + ATTR_VOL_FSTYPE | ATTR_VOL_SIZE | ATTR_VOL_SPACEFREE | + ATTR_VOL_SPACEAVAIL | ATTR_VOL_MINALLOCATION | + ATTR_VOL_OBJCOUNT | ATTR_VOL_MAXOBJCOUNT | + ATTR_VOL_MOUNTPOINT | ATTR_VOL_MOUNTFLAGS | + ATTR_VOL_MOUNTEDDEVICE | ATTR_VOL_CAPABILITIES | + ATTR_VOL_ATTRIBUTES; + fsap->f_attributes.validattr.dirattr = + ATTR_DIR_LINKCOUNT | ATTR_DIR_MOUNTSTATUS; + fsap->f_attributes.validattr.fileattr = + ATTR_FILE_LINKCOUNT | ATTR_FILE_TOTALSIZE | + ATTR_FILE_IOBLOCKSIZE | ATTR_FILE_DEVTYPE | + ATTR_FILE_DATALENGTH; + fsap->f_attributes.validattr.forkattr = 0; + + fsap->f_attributes.nativeattr.commonattr = + ATTR_CMN_NAME | ATTR_CMN_DEVID | ATTR_CMN_FSID | + ATTR_CMN_OBJTYPE | ATTR_CMN_OBJTAG | ATTR_CMN_OBJID | + ATTR_CMN_PAROBJID | + ATTR_CMN_MODTIME | ATTR_CMN_CHGTIME | ATTR_CMN_ACCTIME | + ATTR_CMN_OWNERID | ATTR_CMN_GRPID | ATTR_CMN_ACCESSMASK | + ATTR_CMN_FLAGS | ATTR_CMN_USERACCESS | ATTR_CMN_FILEID; + fsap->f_attributes.nativeattr.volattr = + ATTR_VOL_FSTYPE | ATTR_VOL_SIZE | ATTR_VOL_SPACEFREE | + ATTR_VOL_SPACEAVAIL | ATTR_VOL_MINALLOCATION | + ATTR_VOL_OBJCOUNT | ATTR_VOL_MAXOBJCOUNT | + ATTR_VOL_MOUNTPOINT | ATTR_VOL_MOUNTFLAGS | + ATTR_VOL_MOUNTEDDEVICE | ATTR_VOL_CAPABILITIES | + ATTR_VOL_ATTRIBUTES; + fsap->f_attributes.nativeattr.dirattr = + ATTR_DIR_MOUNTSTATUS; + fsap->f_attributes.nativeattr.fileattr = + ATTR_FILE_LINKCOUNT | ATTR_FILE_TOTALSIZE | + ATTR_FILE_IOBLOCKSIZE | ATTR_FILE_DEVTYPE | + ATTR_FILE_DATALENGTH; + fsap->f_attributes.nativeattr.forkattr = 0; + + VFSATTR_SET_SUPPORTED(fsap, f_attributes); + } + return 0; } static int -devfs_sync(__unused struct mount *mp, __unused int waitfor, __unused vfs_context_t context) +devfs_sync(__unused struct mount *mp, __unused int waitfor, __unused vfs_context_t ctx) { return (0); } static int -devfs_vget(__unused struct mount *mp, __unused ino64_t ino, __unused struct vnode **vpp, __unused vfs_context_t context) +devfs_vget(__unused struct mount *mp, __unused ino64_t ino, __unused struct vnode **vpp, __unused vfs_context_t ctx) { return ENOTSUP; } @@ -313,14 +458,14 @@ devfs_vget(__unused struct mount *mp, __unused ino64_t ino, __unused struct vnod */ static int -devfs_fhtovp (__unused struct mount *mp, __unused int fhlen, __unused unsigned char *fhp, __unused struct vnode **vpp, __unused vfs_context_t context) +devfs_fhtovp (__unused struct mount *mp, __unused int fhlen, __unused unsigned char *fhp, __unused struct vnode **vpp, __unused vfs_context_t ctx) { return (EINVAL); } static int -devfs_vptofh (__unused struct vnode *vp, __unused int *fhlenp, __unused unsigned char *fhp, __unused vfs_context_t context) +devfs_vptofh (__unused struct vnode *vp, __unused int *fhlenp, __unused unsigned char *fhp, __unused vfs_context_t ctx) { return (EINVAL); } @@ -328,7 +473,7 @@ devfs_vptofh (__unused struct vnode *vp, __unused int *fhlenp, __unused unsigned static int devfs_sysctl(__unused int *name, __unused u_int namelen, __unused user_addr_t oldp, __unused size_t *oldlenp, __unused user_addr_t newp, - __unused size_t newlen, __unused vfs_context_t context) + __unused size_t newlen, __unused vfs_context_t ctx) { return (ENOTSUP); } @@ -343,113 +488,30 @@ devfs_sysctl(__unused int *name, __unused u_int namelen, __unused user_addr_t ol int devfs_kernel_mount(char * mntname) { - struct mount *mp; int error; - struct nameidata nd; - struct vnode * vp; - struct vfs_context context; - - if (devfs_vfsp == NULL) { - printf("devfs_kernel_mount: devfs_vfsp is NULL\n"); - return (EINVAL); - } - context.vc_proc = current_proc(); - context.vc_ucred = kauth_cred_get(); - - /* - * Get vnode to be covered - */ - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE32, - CAST_USER_ADDR_T(mntname), &context); - if ((error = namei(&nd))) { - printf("devfs_kernel_mount: failed to find directory '%s', %d", - mntname, error); - return (error); - } - nameidone(&nd); - vp = nd.ni_vp; - - if ((error = VNOP_FSYNC(vp, MNT_WAIT, &context))) { - printf("devfs_kernel_mount: vnop_fsync failed: %d\n", error); - vnode_put(vp); - return (error); - } - if ((error = buf_invalidateblks(vp, BUF_WRITE_DATA, 0, 0))) { - printf("devfs_kernel_mount: buf_invalidateblks failed: %d\n", error); - vnode_put(vp); - return (error); - } - if (vnode_isdir(vp) == 0) { - printf("devfs_kernel_mount: '%s' is not a directory\n", mntname); - vnode_put(vp); - return (ENOTDIR); - } - if ((vnode_mountedhere(vp))) { - vnode_put(vp); - return (EBUSY); - } - - /* - * Allocate and initialize the filesystem. - */ - MALLOC_ZONE(mp, struct mount *, (u_long)sizeof(struct mount), - M_MOUNT, M_WAITOK); - bzero((char *)mp, (u_long)sizeof(struct mount)); - - /* Initialize the default IO constraints */ - mp->mnt_maxreadcnt = mp->mnt_maxwritecnt = MAXPHYS; - mp->mnt_segreadcnt = mp->mnt_segwritecnt = 32; - - mount_lock_init(mp); - TAILQ_INIT(&mp->mnt_vnodelist); - TAILQ_INIT(&mp->mnt_workerqueue); - TAILQ_INIT(&mp->mnt_newvnodes); - - (void)vfs_busy(mp, LK_NOWAIT); - mp->mnt_op = devfs_vfsp->vfc_vfsops; - mp->mnt_vtable = devfs_vfsp; - devfs_vfsp->vfc_refcount++; - devfs_vfsp->vfc_threadsafe = TRUE; - devfs_vfsp->vfc_64bitready = TRUE; - mp->mnt_flag = 0; - mp->mnt_flag |= devfs_vfsp->vfc_flags & MNT_VISFLAGMASK; - strncpy(mp->mnt_vfsstat.f_fstypename, devfs_vfsp->vfc_name, MFSTYPENAMELEN); - vp->v_mountedhere = mp; - mp->mnt_vnodecovered = vp; - mp->mnt_vfsstat.f_owner = kauth_cred_getuid(kauth_cred_get()); - (void) copystr(mntname, mp->mnt_vfsstat.f_mntonname, MAXPATHLEN - 1, 0); - - error = devfs_mount(mp, NULL, NULL, &context); + vfs_context_t ctx = vfs_context_kernel(); + char fsname[] = "devfs"; + error = kernel_mount(fsname, NULLVP, NULLVP, mntname, NULL, 0, MNT_DONTBROWSE, KERNEL_MOUNT_NOAUTH, ctx); if (error) { - printf("devfs_kernel_mount: mount %s failed: %d", mntname, error); - mp->mnt_vtable->vfc_refcount--; - - vfs_unbusy(mp); - - mount_lock_destroy(mp); - FREE_ZONE(mp, sizeof (struct mount), M_MOUNT); - vnode_put(vp); - return (error); + printf("devfs_kernel_mount: kernel_mount failed: %d\n", error); + return (error); } - vnode_ref(vp); - vnode_put(vp); - vfs_unbusy(mp); - mount_list_add(mp); + return (0); } struct vfsops devfs_vfsops = { - devfs_mount, - devfs_start, - devfs_unmount, - devfs_root, - NULL, /* quotactl */ - devfs_vfs_getattr, - devfs_sync, - devfs_vget, - devfs_fhtovp, - devfs_vptofh, - devfs_init, - devfs_sysctl + .vfs_mount = devfs_mount, + .vfs_start = devfs_start, + .vfs_unmount = devfs_unmount, + .vfs_root = devfs_root, + .vfs_getattr = devfs_vfs_getattr, + .vfs_sync = devfs_sync, + .vfs_vget = devfs_vget, + .vfs_fhtovp = devfs_fhtovp, + .vfs_vptofh = devfs_vptofh, + .vfs_init = devfs_init, + .vfs_sysctl = devfs_sysctl, + // There are other VFS ops that we do not support };