From a410b7fd45dde17d545b36b1f5e50d664f65e8c3 Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Wed, 28 Oct 2009 17:54:32 -0400 Subject: [PATCH] Linux - Fix disk cache access for selinux/AppArmor constrained processes Preserve the credentials used for cache initialisation and use then whenever disk cache files are opened. This takes advantage of the credentials separation work from David Howells available in kernels 2.6.29 and above. Access to cache files was done under the security context of the user process, causing processes constrained by selinux or AppArmor to fail to access AFS cache files and causing the cache manager to panic. Besides the RT tickets, should also fix the following Ubuntu bugs: 415766 429260 457779 459299 FIXES 92944,125544 Change-Id: Ief8acd65c1a3e4d8c951f80bfd65f8340b8cec34 Reviewed-on: http://gerrit.openafs.org/752 Reviewed-by: Derrick Brashear Reviewed-by: Russ Allbery Tested-by: Russ Allbery Reviewed-on: http://gerrit.openafs.org/774 --- src/afs/LINUX/osi_file.c | 6 +++++- src/afs/afs_init.c | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/afs/LINUX/osi_file.c b/src/afs/LINUX/osi_file.c index f441c4926..f1dcfc0ea 100644 --- a/src/afs/LINUX/osi_file.c +++ b/src/afs/LINUX/osi_file.c @@ -30,6 +30,9 @@ extern struct osi_dev cacheDev; extern struct vfsmount *afs_cacheMnt; #endif extern struct super_block *afs_cacheSBp; +#if defined(STRUCT_TASK_HAS_CRED) +extern struct cred *cache_creds; +#endif #if defined(AFS_LINUX26_ENV) void * @@ -77,7 +80,8 @@ osi_UFSOpen(afs_int32 ainode) tip->i_flags |= MS_NOATIME; /* Disable updating access times. */ #if defined(STRUCT_TASK_HAS_CRED) - filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR, current_cred()); + /* Use stashed credentials - prevent selinux/apparmor problems */ + filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR, cache_creds); #else filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR); #endif diff --git a/src/afs/afs_init.c b/src/afs/afs_init.c index 2397c7fc9..970c1a8db 100644 --- a/src/afs/afs_init.c +++ b/src/afs/afs_init.c @@ -21,6 +21,9 @@ #include "afs/sysincludes.h" /* Standard vendor system headers */ #include "afsincludes.h" /* Afs-based standard headers */ #include "afs/afs_stats.h" /* afs statistics */ +#if defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_HAS_CRED) +#include +#endif /* Exported variables */ struct osi_dev cacheDev; /*Cache device */ @@ -42,6 +45,9 @@ int afs_memvolumes = 0; #if defined(AFS_XBSD_ENV) static struct vnode *volumeVnode; #endif +#if defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_HAS_CRED) +const struct cred *cache_creds; +#endif /* This is the kernel side of the dynamic vcache setting */ int afsd_dynamic_vcaches = 0; /* Enable dynamic-vcache support */ @@ -138,6 +144,16 @@ afs_CacheInit(afs_int32 astatSize, afs_int32 afiles, afs_int32 ablocks, afs_cacheStats = astatSize; afs_vcacheInit(astatSize); afs_dcacheInit(afiles, ablocks, aDentries, achunk, aflags); +#if defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_HAS_CRED) + /* + * Save current credentials for later access to disk cache files. + * If selinux, apparmor or other security modules are enabled, + * they might deny access to cache files if the userspace process + * is restricted. Save the credentials used at cache initialisation + * for later use when opening cache files. + */ + cache_creds = get_current_cred(); +#endif #ifdef AFS_64BIT_CLIENT #ifdef AFS_VM_RDWR_ENV afs_vmMappingEnd = AFS_CHUNKBASE(0x7fffffff); @@ -685,6 +701,9 @@ shutdown_cache(void) memset((char *)&cacheDev, 0, sizeof(struct osi_dev)); osi_dnlc_shutdown(); } +#if defined(AFS_LINUX26_ENV) && defined(STRUCT_TASK_HAS_CRED) + put_cred(cache_creds); +#endif } /*shutdown_cache */ -- 2.39.5