mirror of https://gitee.com/openkylin/linux.git
ovl: stack fileattr ops
Add stacking for the fileattr operations. Add hack for calling security_file_ioctl() for now. Probably better to have a pair of specific hooks for these operations. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
97e2dee975
commit
66dbfabf10
|
@ -1301,4 +1301,6 @@ const struct inode_operations ovl_dir_inode_operations = {
|
||||||
.listxattr = ovl_listxattr,
|
.listxattr = ovl_listxattr,
|
||||||
.get_acl = ovl_get_acl,
|
.get_acl = ovl_get_acl,
|
||||||
.update_time = ovl_update_time,
|
.update_time = ovl_update_time,
|
||||||
|
.fileattr_get = ovl_fileattr_get,
|
||||||
|
.fileattr_set = ovl_fileattr_set,
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
#include <linux/posix_acl.h>
|
#include <linux/posix_acl.h>
|
||||||
#include <linux/ratelimit.h>
|
#include <linux/ratelimit.h>
|
||||||
#include <linux/fiemap.h>
|
#include <linux/fiemap.h>
|
||||||
|
#include <linux/fileattr.h>
|
||||||
|
#include <linux/security.h>
|
||||||
#include "overlayfs.h"
|
#include "overlayfs.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -500,6 +502,79 @@ static int ovl_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Work around the fact that security_file_ioctl() takes a file argument.
|
||||||
|
* Introducing security_inode_fileattr_get/set() hooks would solve this issue
|
||||||
|
* properly.
|
||||||
|
*/
|
||||||
|
static int ovl_security_fileattr(struct dentry *dentry, struct fileattr *fa,
|
||||||
|
bool set)
|
||||||
|
{
|
||||||
|
struct path realpath;
|
||||||
|
struct file *file;
|
||||||
|
unsigned int cmd;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
ovl_path_real(dentry, &realpath);
|
||||||
|
file = dentry_open(&realpath, O_RDONLY, current_cred());
|
||||||
|
if (IS_ERR(file))
|
||||||
|
return PTR_ERR(file);
|
||||||
|
|
||||||
|
if (set)
|
||||||
|
cmd = fa->fsx_valid ? FS_IOC_FSSETXATTR : FS_IOC_SETFLAGS;
|
||||||
|
else
|
||||||
|
cmd = fa->fsx_valid ? FS_IOC_FSGETXATTR : FS_IOC_GETFLAGS;
|
||||||
|
|
||||||
|
err = security_file_ioctl(file, cmd, 0);
|
||||||
|
fput(file);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ovl_fileattr_set(struct user_namespace *mnt_userns,
|
||||||
|
struct dentry *dentry, struct fileattr *fa)
|
||||||
|
{
|
||||||
|
struct inode *inode = d_inode(dentry);
|
||||||
|
struct dentry *upperdentry;
|
||||||
|
const struct cred *old_cred;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = ovl_want_write(dentry);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
err = ovl_copy_up(dentry);
|
||||||
|
if (!err) {
|
||||||
|
upperdentry = ovl_dentry_upper(dentry);
|
||||||
|
|
||||||
|
old_cred = ovl_override_creds(inode->i_sb);
|
||||||
|
err = ovl_security_fileattr(dentry, fa, true);
|
||||||
|
if (!err)
|
||||||
|
err = vfs_fileattr_set(&init_user_ns, upperdentry, fa);
|
||||||
|
revert_creds(old_cred);
|
||||||
|
ovl_copyflags(ovl_inode_real(inode), inode);
|
||||||
|
}
|
||||||
|
ovl_drop_write(dentry);
|
||||||
|
out:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ovl_fileattr_get(struct dentry *dentry, struct fileattr *fa)
|
||||||
|
{
|
||||||
|
struct inode *inode = d_inode(dentry);
|
||||||
|
struct dentry *realdentry = ovl_dentry_real(dentry);
|
||||||
|
const struct cred *old_cred;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
old_cred = ovl_override_creds(inode->i_sb);
|
||||||
|
err = ovl_security_fileattr(dentry, fa, false);
|
||||||
|
if (!err)
|
||||||
|
err = vfs_fileattr_get(realdentry, fa);
|
||||||
|
revert_creds(old_cred);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct inode_operations ovl_file_inode_operations = {
|
static const struct inode_operations ovl_file_inode_operations = {
|
||||||
.setattr = ovl_setattr,
|
.setattr = ovl_setattr,
|
||||||
.permission = ovl_permission,
|
.permission = ovl_permission,
|
||||||
|
@ -508,6 +583,8 @@ static const struct inode_operations ovl_file_inode_operations = {
|
||||||
.get_acl = ovl_get_acl,
|
.get_acl = ovl_get_acl,
|
||||||
.update_time = ovl_update_time,
|
.update_time = ovl_update_time,
|
||||||
.fiemap = ovl_fiemap,
|
.fiemap = ovl_fiemap,
|
||||||
|
.fileattr_get = ovl_fileattr_get,
|
||||||
|
.fileattr_set = ovl_fileattr_set,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct inode_operations ovl_symlink_inode_operations = {
|
static const struct inode_operations ovl_symlink_inode_operations = {
|
||||||
|
|
|
@ -521,6 +521,9 @@ int __init ovl_aio_request_cache_init(void);
|
||||||
void ovl_aio_request_cache_destroy(void);
|
void ovl_aio_request_cache_destroy(void);
|
||||||
long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
||||||
long ovl_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
long ovl_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
||||||
|
int ovl_fileattr_get(struct dentry *dentry, struct fileattr *fa);
|
||||||
|
int ovl_fileattr_set(struct user_namespace *mnt_userns,
|
||||||
|
struct dentry *dentry, struct fileattr *fa);
|
||||||
|
|
||||||
/* copy_up.c */
|
/* copy_up.c */
|
||||||
int ovl_copy_up(struct dentry *dentry);
|
int ovl_copy_up(struct dentry *dentry);
|
||||||
|
|
Loading…
Reference in New Issue