From 57b4f4f9be1e25d5609301c10f717aff32aef676 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Fri, 13 Mar 2020 13:00:35 -0500 Subject: [PATCH] LINUX: Properly revert creds in osi_UFSTruncate Commit cd3221d3 (Linux: use override_creds when available) caused us to force the current process's creds to the creds of afsd during osi_file.c file ops, to avoid access errors in some cases. However, in osi_UFSTruncate, one code path was missed to revert our creds back to the original user's creds: when the afs_osi_Stat call fails or deems the truncate unnecessary. In this case, the calling process keeps the creds for afsd after osi_UFSTruncate returns, causing our subsequent access-checking code to think that the current process is in the same context as afsd (typically uid 0 without a pag). This can cause the calling process to appear to transiently have the same access as non-pag uid 0; typically this will be unauthenticated access, but could be authenticated if uid 0 has tokens. To fix this, modify the early return in osi_UFSTruncate to go through a 'goto done' destructor instead, and make sure we revert our creds in that destructor. Thanks to cwills@sinenomine.net for finding and helping reproduce the issue. Change-Id: I6820af675edcb7aa00542ba40fc52430d68c05e8 Reviewed-on: https://gerrit.openafs.org/14098 Tested-by: BuildBot Reviewed-by: Benjamin Kaduk Reviewed-by: Jeffrey Hutzelman Reviewed-by: Cheyenne Wills Tested-by: Cheyenne Wills --- src/afs/LINUX/osi_file.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/afs/LINUX/osi_file.c b/src/afs/LINUX/osi_file.c index 7a14729..e2218ad 100644 --- a/src/afs/LINUX/osi_file.c +++ b/src/afs/LINUX/osi_file.c @@ -218,7 +218,7 @@ osi_UFSTruncate(struct osi_file *afile, afs_int32 asize) #endif code = afs_osi_Stat(afile, &tstat); if (code || tstat.size <= asize) - return code; + goto done; AFS_GUNLOCK(); afs_linux_lock_inode(inode); #ifdef STRUCT_INODE_HAS_I_ALLOC_SEM @@ -243,10 +243,11 @@ osi_UFSTruncate(struct osi_file *afile, afs_int32 asize) up_write(&inode->i_alloc_sem); #endif afs_linux_unlock_inode(inode); + AFS_GLOCK(); + done: #if defined(HAVE_LINUX_OVERRIDE_CREDS) revert_creds(cur_cred); #endif - AFS_GLOCK(); return code; } -- 1.7.1