LINUX: Always crref after _settok_setParentPag 47/14147/2
authorYadavendra Yadav <yadayada@in.ibm.com>
Wed, 15 Apr 2020 10:33:00 +0000 (05:33 -0500)
committerBenjamin Kaduk <kaduk@mit.edu>
Fri, 17 Apr 2020 16:40:10 +0000 (12:40 -0400)
Commit b61eac78 (Linux: setpag() may replace credentials) changed
PSetTokens2 to call crref() after _settok_setParentPag(), since
changing the parent PAG may change our credentials structure. But that
commit did not update the old pioctl PSetTokens, so -setpag
functionality remained broken on Linux for utilities that called the
old pioctl ('klog' is one such utility).

To fix this, we could copy the same code from PSetTokens2 into
PSetTokens. But instead just move this code into _settok_setParentPag
itself, to avoid code duplication. This commit also refactors
_settok_setParentPag a little to make the platform-specific ifdefs a
little easier to read through.

Change-Id: I65a165ebb1d823e690926de31b28a7728d2561b9
Reviewed-on: https://gerrit.openafs.org/14147
Reviewed-by: Andrew Deason <adeason@sinenomine.net>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Yadavendra Yadav <yadayada@in.ibm.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>

src/afs/afs_pioctl.c

index 1f36540..e2ece01 100644 (file)
@@ -1830,19 +1830,40 @@ _settok_tokenCell(char *cellName, int *cellNum, int *primary) {
 }
 
 
+#if defined(AFS_LINUX26_ENV)
 static_inline int
-_settok_setParentPag(afs_ucred_t **cred) {
+_settok_setParentPag(afs_ucred_t **cred)
+{
+    afs_uint32 pag;
+    int code;
+    afs_ucred_t *old_cred = *cred;
+    code = setpag(cred, -1, &pag, 1);
+    if (code == 0) {
+       /* setpag() may have changed our credentials */
+       *cred = crref();
+       crfree(old_cred);
+    }
+    return code;
+}
+#elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
+static_inline int
+_settok_setParentPag(afs_ucred_t **cred)
+{
     afs_uint32 pag;
-#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
     char procname[256];
     osi_procname(procname, 256);
     afs_warnuser("Process %d (%s) tried to change pags in PSetTokens\n",
                 MyPidxx2Pid(MyPidxx), procname);
     return setpag(osi_curproc(), cred, -1, &pag, 1);
+}
 #else
+static_inline int
+_settok_setParentPag(afs_ucred_t **cred)
+{
+    afs_uint32 pag;
     return setpag(cred, -1, &pag, 1);
-#endif
 }
+#endif
 
 /*!
  * VIOCSETTOK (3) - Set authentication tokens
@@ -5363,15 +5384,7 @@ DECL_PIOCTL(PSetTokens2)
     }
 
     if (tokenSet.flags & AFSTOKEN_EX_SETPAG) {
-#if defined(AFS_LINUX26_ENV)
-       afs_ucred_t *old_cred = *acred;
-#endif
        if (_settok_setParentPag(acred) == 0) {
-#if defined(AFS_LINUX26_ENV)
-           /* setpag() may have changed our credentials */
-           *acred = crref();
-           crfree(old_cred);
-#endif
            code = afs_CreateReq(&treq, *acred);
            if (code) {
                xdr_free((xdrproc_t) xdr_ktc_setTokenData, &tokenSet);