summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@google.com>2017-07-06 19:12:22 -0700
committerDaniel Rosenberg <drosen@google.com>2017-08-08 16:15:27 -0700
commitb315101a358facc225f4bdeff1adc4b0b95f95c9 (patch)
treea0917f0e46c240375b6a60ec364966a9062ba8bd
parent9f764bbe06d6ff340bb5c30bc8f73c4fe139df80 (diff)
ANDROID: sdcardfs: override credential for ioctl to lower fs
Otherwise, lower_fs->ioctl() fails due to inode_owner_or_capable(). Signed-off-by: Jaegeuk Kim <jaegeuk@google.com> Bug: 63260873 Change-Id: I623a6c7c5f8a3cbd7ec73ef89e18ddb093c43805
-rw-r--r--fs/sdcardfs/file.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/fs/sdcardfs/file.c b/fs/sdcardfs/file.c
index 6076c342dae6..5ac0b0bbb0ec 100644
--- a/fs/sdcardfs/file.c
+++ b/fs/sdcardfs/file.c
@@ -104,12 +104,19 @@ static long sdcardfs_unlocked_ioctl(struct file *file, unsigned int cmd,
{
long err = -ENOTTY;
struct file *lower_file;
+ const struct cred *saved_cred = NULL;
+ struct dentry *dentry = file->f_path.dentry;
+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
lower_file = sdcardfs_lower_file(file);
/* XXX: use vfs_ioctl if/when VFS exports it */
if (!lower_file || !lower_file->f_op)
goto out;
+
+ /* save current_cred and override it */
+ OVERRIDE_CRED(sbi, saved_cred, SDCARDFS_I(file_inode(file)));
+
if (lower_file->f_op->unlocked_ioctl)
err = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg);
@@ -117,6 +124,7 @@ static long sdcardfs_unlocked_ioctl(struct file *file, unsigned int cmd,
if (!err)
sdcardfs_copy_and_fix_attrs(file_inode(file),
file_inode(lower_file));
+ REVERT_CRED(saved_cred);
out:
return err;
}
@@ -127,15 +135,23 @@ static long sdcardfs_compat_ioctl(struct file *file, unsigned int cmd,
{
long err = -ENOTTY;
struct file *lower_file;
+ const struct cred *saved_cred = NULL;
+ struct dentry *dentry = file->f_path.dentry;
+ struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb);
lower_file = sdcardfs_lower_file(file);
/* XXX: use vfs_ioctl if/when VFS exports it */
if (!lower_file || !lower_file->f_op)
goto out;
+
+ /* save current_cred and override it */
+ OVERRIDE_CRED(sbi, saved_cred, SDCARDFS_I(file_inode(file)));
+
if (lower_file->f_op->compat_ioctl)
err = lower_file->f_op->compat_ioctl(lower_file, cmd, arg);
+ REVERT_CRED(saved_cred);
out:
return err;
}