DARWIN: Replace afs_osi_cred by allocated ucred 22/14922/7
authorMarcio Barbosa <mbarbosa@sinenomine.net>
Tue, 15 Mar 2022 13:38:45 +0000 (10:38 -0300)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 13 May 2022 17:26:49 +0000 (13:26 -0400)
Building the current version of OpenAFS on macOS Monterey arm64 results
in the following error:

 error: globals with authenticated null values are currently unsupported
 afs_ucred_t afs_osi_cred;

To avoid this problem, replace the global in question by a pointer to a
dynamically allocated afs_osi_cred (afs_osi_credp). Ideally we would
create a new credential with kauth_cred_create(), but this function is
not well documented and using it results in crashes. Moreover, if the
kauth_cred_dup() function were still available (private since XNU
1456.1.26 - macOS 10.6), we could also duplicate the current user's
credential during startup (like commit f40f466c7f did for BSD).

Change-Id: Ied2df7590e4e671ce2643669c83ee0e4b2a97cd1
Reviewed-on: https://gerrit.openafs.org/14922
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Tested-by: BuildBot <buildbot@rampaginggeek.com>

src/afs/DARWIN/osi_file.c
src/afs/DARWIN/osi_inode.c
src/afs/DARWIN/osi_machdep.h
src/afs/DARWIN/osi_vnodeops.c
src/afs/afs_osi.c

index 7c1539e..4d525fe 100644 (file)
@@ -18,7 +18,6 @@
 
 
 int afs_osicred_initialized = 0;
-afs_ucred_t afs_osi_cred;
 extern struct osi_dev cacheDev;
 extern struct mount *afs_cacheVfsp;
 int afs_CacheFSType = -1;
@@ -85,7 +84,7 @@ VnodeToIno(vnode_t avp)
        ret = va.va_fileid;
 #elif !defined(VTOH)
        struct vattr va;
-       if (VOP_GETATTR(avp, &va, &afs_osi_cred, current_proc()))
+       if (VOP_GETATTR(avp, &va, afs_osi_credp, current_proc()))
            osi_Panic("VOP_GETATTR failed in VnodeToIno\n");
        ret = va.va_fileid;
 #else
@@ -120,7 +119,7 @@ VnodeToDev(vnode_t avp)
        return va.va_fsid;      /* XXX they say it's the dev.... */
 #elif !defined(VTOH)
        struct vattr va;
-       if (VOP_GETATTR(avp, &va, &afs_osi_cred, current_proc()))
+       if (VOP_GETATTR(avp, &va, afs_osi_credp, current_proc()))
            osi_Panic("VOP_GETATTR failed in VnodeToDev\n");
        return va.va_fsid;      /* XXX they say it's the dev.... */
 #else
@@ -150,10 +149,12 @@ osi_UFSOpen(afs_dcache_id_t *ainode)
        osi_Panic("UFSOpen called for non-UFS cache\n");
     }
     if (!afs_osicred_initialized) {
-       memset(&afs_osi_cred, 0, sizeof(afs_ucred_t));
-       afs_osi_cred.cr_ref++;
+       afs_osi_credp = afs_osi_Alloc(sizeof(*afs_osi_credp));
+       osi_Assert(afs_osi_credp != NULL);
+       memset(afs_osi_credp, 0, sizeof(*afs_osi_credp));
+       afs_osi_credp->cr_ref++;
 #ifndef AFS_DARWIN110_ENV
-       afs_osi_cred.cr_ngroups = 1;
+       afs_osi_credp->cr_ngroups = 1;
 #endif
        afs_osicred_initialized = 1;
     }
@@ -213,7 +214,7 @@ afs_osi_Stat(struct osi_file *afile, struct osi_stat *astat)
     if (code == 0 && !VATTR_ALL_SUPPORTED(&tvattr))
        code = EINVAL;
 #else
-    code = VOP_GETATTR(afile->vnode, &tvattr, &afs_osi_cred, current_proc());
+    code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, current_proc());
 #endif
     AFS_GLOCK();
     if (code == 0) {
@@ -264,7 +265,7 @@ osi_UFSTruncate(struct osi_file *afile, afs_int32 asize)
 #else
     VATTR_NULL(&tvattr);
     tvattr.va_size = asize;
-    code = VOP_SETATTR(afile->vnode, &tvattr, &afs_osi_cred, current_proc());
+    code = VOP_SETATTR(afile->vnode, &tvattr, afs_osi_credp, current_proc());
 #endif
     AFS_GLOCK();
     return code;
@@ -334,7 +335,7 @@ afs_osi_Read(struct osi_file *afile, int offset, void *aptr,
 #else
     code =
        gop_rdwr(UIO_READ, afile->vnode, (caddr_t) aptr, asize, afile->offset,
-                AFS_UIOSYS, IO_UNIT, &afs_osi_cred, &resid);
+                AFS_UIOSYS, IO_UNIT, afs_osi_credp, &resid);
 #endif
     AFS_GLOCK();
     if (code == 0) {
@@ -378,7 +379,7 @@ afs_osi_Write(struct osi_file *afile, afs_int32 offset, void *aptr,
 #else
        code =
            gop_rdwr(UIO_WRITE, afile->vnode, (caddr_t) aptr, asize,
-                    afile->offset, AFS_UIOSYS, IO_UNIT, &afs_osi_cred,
+                    afile->offset, AFS_UIOSYS, IO_UNIT, afs_osi_credp,
                     &resid);
 #endif
        AFS_GLOCK();
@@ -406,6 +407,10 @@ shutdown_osifile(void)
 {
     AFS_STATCNT(shutdown_osifile);
     if (afs_cold_shutdown) {
+       if (afs_osi_credp != NULL) {
+           afs_osi_Free(afs_osi_credp, sizeof(*afs_osi_credp));
+           afs_osi_credp = NULL;
+       }
        afs_osicred_initialized = 0;
     }
 }
index 1a7ca31..e3d6866 100644 (file)
@@ -23,7 +23,7 @@
 #ifndef AFS_DARWIN80_ENV
 #include <ufs/ufs/ufsmount.h>
 #endif
-extern struct ucred afs_osi_cred;
+extern struct ucred *afs_osi_credp;
 extern int afs_CacheFSType;
 
 #ifdef AFS_DARWIN80_ENV
@@ -187,7 +187,7 @@ igetinode(vfsp, dev, inode, vpp, va, perror)
        iforget(vp);
        return (ENOENT);
     }
-    VOP_GETATTR(vp, va, &afs_osi_cred, current_proc());
+    VOP_GETATTR(vp, va, afs_osi_credp, current_proc());
     if (va->va_mode == 0) {
        /* Not an allocated inode */
        iforget(vp);
index b360970..5bc39f5 100644 (file)
@@ -203,7 +203,7 @@ extern int igetinode(mount_t vfsp, dev_t dev , ino_t inode, vnode_t *vpp,
 #define osi_curproc() current_proc()
 
 /* FIXME */
-#define osi_curcred() &afs_osi_cred
+#define osi_curcred() afs_osi_credp
 
 #ifdef AFS_DARWIN80_ENV
 # define afsio_free(X) uio_free(X)
index a3c222a..0405bc9 100644 (file)
@@ -529,7 +529,7 @@ afs_vop_close(ap)
     if (vop_cred)
        code = afs_close(avc, ap->a_fflag, vop_cred);
     else
-       code = afs_close(avc, ap->a_fflag, &afs_osi_cred);
+       code = afs_close(avc, ap->a_fflag, afs_osi_credp);
     osi_FlushPages(avc, vop_cred);     /* hold GLOCK, but not basic vnode lock */
     /* This is legit; it just forces the fstrace event to happen */
     code = afs_CheckCode(code, NULL, 60);
@@ -1213,7 +1213,7 @@ afs_vop_fsync(ap)
     if (vop_cred)
        error = afs_fsync(VTOAFS(vp), vop_cred);
     else
-       error = afs_fsync(VTOAFS(vp), &afs_osi_cred);
+       error = afs_fsync(VTOAFS(vp), afs_osi_credp);
     if (!haveGlock) AFS_GUNLOCK();
     return error;
 }
index 1a634e8..bcd78de 100644 (file)
@@ -94,17 +94,20 @@ osi_Init(void)
          crdup(osi_curcred());
 #elif defined(AFS_SUN5_ENV)
        afs_osi_credp = kcred;
+#elif defined(AFS_DARWIN_ENV)
+       afs_osi_credp = afs_osi_Alloc(sizeof(*afs_osi_credp));
+       osi_Assert(afs_osi_credp != NULL);
+       memset(afs_osi_credp, 0, sizeof(*afs_osi_credp));
+# if defined(AFS_DARWIN80_ENV)
+       afs_osi_credp->cr_ref = 1; /* kauth_cred_get_ref needs 1 existing ref */
+# endif
 #else
        memset(&afs_osi_cred, 0, sizeof(afs_ucred_t));
 #if defined(AFS_LINUX_ENV)
         afs_set_cr_group_info(&afs_osi_cred, groups_alloc(0));
 #endif
-#if defined(AFS_DARWIN80_ENV)
-        afs_osi_cred.cr_ref = 1; /* kauth_cred_get_ref needs 1 existing ref */
-#else
-# if !(defined(AFS_LINUX_ENV) && defined(STRUCT_TASK_STRUCT_HAS_CRED))
+#if !(defined(AFS_LINUX_ENV) && defined(STRUCT_TASK_STRUCT_HAS_CRED))
        crhold(&afs_osi_cred);  /* don't let it evaporate */
-# endif
 #endif
 
        afs_osi_credp = &afs_osi_cred;