]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/miscfs/nullfs/null_vfsops.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / bsd / miscfs / nullfs / null_vfsops.c
index 0e8330da7bacc2271be18312512477824a8607af..c0f5ac6e7fe38de0259b77598121d42cdcf10a89 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2019 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -70,6 +70,7 @@
 #include <sys/vnode.h>
 #include <sys/vnode_internal.h>
 #include <security/mac_internal.h>
+#include <sys/kauth.h>
 
 #include <sys/param.h>
 
@@ -110,7 +111,9 @@ nullfs_mount(struct mount * mp, __unused vnode_t devvp, user_addr_t user_data, v
        struct vnode *lowerrootvp = NULL, *vp = NULL;
        struct vfsstatfs * sp   = NULL;
        struct null_mount * xmp = NULL;
-       char data[MAXPATHLEN];
+       struct null_mount_conf conf = {0};
+       char path[MAXPATHLEN];
+
        size_t count;
        struct vfs_attr vfa;
        /* set defaults (arbitrary since this file system is readonly) */
@@ -143,10 +146,19 @@ nullfs_mount(struct mount * mp, __unused vnode_t devvp, user_addr_t user_data, v
                return EPERM;
        }
 
+       /*
+        * Get configuration
+        */
+       error = copyin(user_data, &conf, sizeof(conf));
+       if (error) {
+               NULLFSDEBUG("nullfs: error copying configuration form user %d\n", error);
+               goto error;
+       }
+
        /*
         * Get argument
         */
-       error = copyinstr(user_data, data, MAXPATHLEN - 1, &count);
+       error = copyinstr(user_data + sizeof(conf), path, MAXPATHLEN - 1, &count);
        if (error) {
                NULLFSDEBUG("nullfs: error copying data form user %d\n", error);
                goto error;
@@ -156,13 +168,13 @@ nullfs_mount(struct mount * mp, __unused vnode_t devvp, user_addr_t user_data, v
         * 64 bit */
        if (count > MAX_MNT_FROM_LENGTH) {
                error = EINVAL;
-               NULLFSDEBUG("nullfs: path to translocate too large for this system %d vs %d\n", count, MAX_MNT_FROM_LENGTH);
+               NULLFSDEBUG("nullfs: path to translocate too large for this system %ld vs %ld\n", count, MAX_MNT_FROM_LENGTH);
                goto error;
        }
 
-       error = vnode_lookup(data, 0, &lowerrootvp, ctx);
+       error = vnode_lookup(path, 0, &lowerrootvp, ctx);
        if (error) {
-               NULLFSDEBUG("lookup %s -> %d\n", data, error);
+               NULLFSDEBUG("lookup %s -> %d\n", path, error);
                goto error;
        }
 
@@ -177,7 +189,7 @@ nullfs_mount(struct mount * mp, __unused vnode_t devvp, user_addr_t user_data, v
                goto error;
        }
 
-       NULLFSDEBUG("mount %s\n", data);
+       NULLFSDEBUG("mount %s\n", path);
 
        MALLOC(xmp, struct null_mount *, sizeof(*xmp), M_TEMP, M_WAITOK | M_ZERO);
        if (xmp == NULL) {
@@ -185,6 +197,12 @@ nullfs_mount(struct mount * mp, __unused vnode_t devvp, user_addr_t user_data, v
                goto error;
        }
 
+       /*
+        * Grab the uid/gid of the caller, which may be used for unveil later
+        */
+       xmp->uid = kauth_cred_getuid(cred);
+       xmp->gid = kauth_cred_getgid(cred);
+
        /*
         * Save reference to underlying FS
         */
@@ -203,10 +221,7 @@ nullfs_mount(struct mount * mp, __unused vnode_t devvp, user_addr_t user_data, v
        vnode_ref(vp);
        vnode_put(vp);
 
-       error = nullfs_init_lck(&xmp->nullm_lock);
-       if (error) {
-               goto error;
-       }
+       nullfs_init_lck(&xmp->nullm_lock);
 
        xmp->nullm_rootvp = vp;
 
@@ -229,12 +244,15 @@ nullfs_mount(struct mount * mp, __unused vnode_t devvp, user_addr_t user_data, v
 
        /* fill in the stat block */
        sp = vfs_statfs(mp);
-       strlcpy(sp->f_mntfromname, data, MAX_MNT_FROM_LENGTH);
+       strlcpy(sp->f_mntfromname, path, MAX_MNT_FROM_LENGTH);
 
        sp->f_flags = flags;
 
        xmp->nullm_flags = NULLM_CASEINSENSITIVE; /* default to case insensitive */
 
+       // Set the flags that are requested
+       xmp->nullm_flags |= conf.flags & NULLM_UNVEIL;
+
        error = nullfs_vfs_getlowerattr(vnode_mount(lowerrootvp), &vfa, ctx);
        if (error == 0) {
                if (VFSATTR_IS_SUPPORTED(&vfa, f_bsize)) {
@@ -407,8 +425,9 @@ nullfs_vfs_getattr(struct mount * mp, struct vfs_attr * vfap, vfs_context_t ctx)
        struct null_mount * null_mp = MOUNTTONULLMOUNT(mp);
        vol_capabilities_attr_t capabilities;
        struct vfsstatfs * sp = vfs_statfs(mp);
+       vfs_context_t ectx = nullfs_get_patched_context(null_mp, ctx);
 
-       struct timespec tzero = {0, 0};
+       struct timespec tzero = {.tv_sec = 0, .tv_nsec = 0};
 
        NULLFSDEBUG("%s\n", __FUNCTION__);
 
@@ -417,7 +436,7 @@ nullfs_vfs_getattr(struct mount * mp, struct vfs_attr * vfap, vfs_context_t ctx)
        capabilities.capabilities[VOL_CAPABILITIES_FORMAT] = VOL_CAP_FMT_FAST_STATFS | VOL_CAP_FMT_HIDDEN_FILES;
        capabilities.valid[VOL_CAPABILITIES_FORMAT]        = VOL_CAP_FMT_FAST_STATFS | VOL_CAP_FMT_HIDDEN_FILES;
 
-       if (nullfs_vfs_getlowerattr(vnode_mount(null_mp->nullm_lowerrootvp), &vfa, ctx) == 0) {
+       if (nullfs_vfs_getlowerattr(vnode_mount(null_mp->nullm_lowerrootvp), &vfa, ectx) == 0) {
                if (VFSATTR_IS_SUPPORTED(&vfa, f_capabilities)) {
                        memcpy(&capabilities, &vfa.f_capabilities, sizeof(capabilities));
                        /* don't support vget */
@@ -528,6 +547,8 @@ nullfs_vfs_getattr(struct mount * mp, struct vfs_attr * vfap, vfs_context_t ctx)
                }
        }
 
+       nullfs_cleanup_patched_context(null_mp, ectx);
+
        return 0;
 }
 
@@ -549,9 +570,9 @@ nullfs_vfs_start(__unused struct mount * mp, __unused int flags, __unused vfs_co
        return 0;
 }
 
-extern struct vnodeopv_desc nullfs_vnodeop_opv_desc;
+extern const struct vnodeopv_desc nullfs_vnodeop_opv_desc;
 
-struct vnodeopv_desc * nullfs_vnodeopv_descs[] = {
+const struct vnodeopv_desc * nullfs_vnodeopv_descs[] = {
        &nullfs_vnodeop_opv_desc,
 };