mirror of
https://git.openafs.org/openafs.git
synced 2025-01-31 05:27:44 +00:00
Linux: use override_creds when available
Linux may perform some access control checks at the time of an I/O operation, rather than relying solely on checks done when the file is opened. In some cases (e.g. AppArmor), these checks are done based on the current tasks's creds at the time of the I/O operation, not those used when the file was open. Because of this, we must use override_creds() / revert_creds() to make sure we are using privileged credentials when performing I/O operations on cache files. Otherwise, cache I/O operations done in the context of a task with a restrictive AppArmor profile will fail. Change-Id: Icbe60874c348d6cd92b0a186d426918b0db9b0f9 Reviewed-on: https://gerrit.openafs.org/13751 Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Andrew Deason <adeason@sinenomine.net> Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
This commit is contained in:
parent
042f809ccf
commit
cd3221d353
@ -59,6 +59,9 @@ afs_linux_raw_open(afs_dcache_id_t *ainode)
|
||||
struct inode *tip = NULL;
|
||||
struct dentry *dp = NULL;
|
||||
struct file* filp;
|
||||
#if defined(HAVE_LINUX_OVERRIDE_CREDS)
|
||||
const struct cred *cur_cred;
|
||||
#endif
|
||||
|
||||
dp = afs_get_dentry_from_fh(afs_cacheSBp, ainode, cache_fh_len, cache_fh_type,
|
||||
afs_fh_acceptable);
|
||||
@ -67,6 +70,9 @@ afs_linux_raw_open(afs_dcache_id_t *ainode)
|
||||
tip = dp->d_inode;
|
||||
tip->i_flags |= S_NOATIME; /* Disable updating access times. */
|
||||
|
||||
#if defined(HAVE_LINUX_OVERRIDE_CREDS)
|
||||
cur_cred = override_creds(cache_creds);
|
||||
#endif
|
||||
#if defined(STRUCT_TASK_STRUCT_HAS_CRED)
|
||||
/* Use stashed credentials - prevent selinux/apparmor problems */
|
||||
filp = afs_dentry_open(dp, afs_cacheMnt, O_RDWR, cache_creds);
|
||||
@ -74,6 +80,9 @@ afs_linux_raw_open(afs_dcache_id_t *ainode)
|
||||
filp = afs_dentry_open(dp, afs_cacheMnt, O_RDWR, current_cred());
|
||||
#else
|
||||
filp = dentry_open(dget(dp), mntget(afs_cacheMnt), O_RDWR);
|
||||
#endif
|
||||
#if defined(HAVE_LINUX_OVERRIDE_CREDS)
|
||||
revert_creds(cur_cred);
|
||||
#endif
|
||||
if (IS_ERR(filp)) {
|
||||
afs_warn("afs: Cannot open cache file (code %d). Trying to continue, "
|
||||
@ -168,10 +177,20 @@ afs_osi_Stat(struct osi_file *afile, struct osi_stat *astat)
|
||||
int
|
||||
osi_UFSClose(struct osi_file *afile)
|
||||
{
|
||||
#if defined(HAVE_LINUX_OVERRIDE_CREDS)
|
||||
const struct cred *cur_cred;
|
||||
#endif
|
||||
|
||||
AFS_STATCNT(osi_Close);
|
||||
if (afile) {
|
||||
if (OSIFILE_INODE(afile)) {
|
||||
#if defined(HAVE_LINUX_OVERRIDE_CREDS)
|
||||
cur_cred = override_creds(cache_creds);
|
||||
#endif
|
||||
filp_close(afile->filp, NULL);
|
||||
#if defined(HAVE_LINUX_OVERRIDE_CREDS)
|
||||
revert_creds(cur_cred);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
kfree(afile);
|
||||
@ -185,12 +204,18 @@ osi_UFSTruncate(struct osi_file *afile, afs_int32 asize)
|
||||
struct osi_stat tstat;
|
||||
struct iattr newattrs;
|
||||
struct inode *inode = OSIFILE_INODE(afile);
|
||||
#if defined(HAVE_LINUX_OVERRIDE_CREDS)
|
||||
const struct cred *cur_cred;
|
||||
#endif
|
||||
AFS_STATCNT(osi_Truncate);
|
||||
|
||||
/* This routine only shrinks files, and most systems
|
||||
* have very slow truncates, even when the file is already
|
||||
* small enough. Check now and save some time.
|
||||
*/
|
||||
#if defined(HAVE_LINUX_OVERRIDE_CREDS)
|
||||
cur_cred = override_creds(cache_creds);
|
||||
#endif
|
||||
code = afs_osi_Stat(afile, &tstat);
|
||||
if (code || tstat.size <= asize)
|
||||
return code;
|
||||
@ -218,6 +243,9 @@ osi_UFSTruncate(struct osi_file *afile, afs_int32 asize)
|
||||
up_write(&inode->i_alloc_sem);
|
||||
#endif
|
||||
afs_linux_unlock_inode(inode);
|
||||
#if defined(HAVE_LINUX_OVERRIDE_CREDS)
|
||||
revert_creds(cur_cred);
|
||||
#endif
|
||||
AFS_GLOCK();
|
||||
return code;
|
||||
}
|
||||
@ -379,6 +407,9 @@ osi_rdwr(struct osi_file *osifile, struct uio *uiop, int rw)
|
||||
size_t count;
|
||||
unsigned long savelim;
|
||||
loff_t pos;
|
||||
#if defined(HAVE_LINUX_OVERRIDE_CREDS)
|
||||
const struct cred *cur_cred = override_creds(cache_creds);
|
||||
#endif
|
||||
|
||||
savelim = current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur;
|
||||
current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
|
||||
@ -434,6 +465,9 @@ osi_rdwr(struct osi_file *osifile, struct uio *uiop, int rw)
|
||||
#endif /* AFS_FILE_NEEDS_SET_FS */
|
||||
|
||||
current->TASK_STRUCT_RLIM[RLIMIT_FSIZE].rlim_cur = savelim;
|
||||
#if defined(HAVE_LINUX_OVERRIDE_CREDS)
|
||||
revert_creds(cur_cred);
|
||||
#endif
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -86,6 +86,9 @@ AC_CHECK_LINUX_FUNC([ktime_get_real_ts64],
|
||||
AC_CHECK_LINUX_FUNC([locks_lock_file_wait],
|
||||
[#include <linux/fs.h>],
|
||||
[locks_lock_file_wait(NULL, NULL);])
|
||||
AC_CHECK_LINUX_FUNC([override_creds],
|
||||
[#include <linux/cred.h>],
|
||||
[override_creds(0);])
|
||||
AC_CHECK_LINUX_FUNC([page_follow_link],
|
||||
[#include <linux/fs.h>],
|
||||
[page_follow_link(0,0);])
|
||||
|
Loading…
x
Reference in New Issue
Block a user