mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
Merge branch 'work.gfs2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull gfs2 setattr updates from Al Viro: "Make it possible for filesystems to use a generic 'may_setattr()' and switch gfs2 to using it" * 'work.gfs2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: gfs2: Switch to may_setattr in gfs2_setattr fs: Move notify_change permission checks into may_setattr
This commit is contained in:
commit
7b871c7713
50
fs/attr.c
50
fs/attr.c
@ -249,6 +249,34 @@ void setattr_copy(struct user_namespace *mnt_userns, struct inode *inode,
|
||||
}
|
||||
EXPORT_SYMBOL(setattr_copy);
|
||||
|
||||
int may_setattr(struct user_namespace *mnt_userns, struct inode *inode,
|
||||
unsigned int ia_valid)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
|
||||
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/*
|
||||
* If utimes(2) and friends are called with times == NULL (or both
|
||||
* times are UTIME_NOW), then we need to check for write permission
|
||||
*/
|
||||
if (ia_valid & ATTR_TOUCH) {
|
||||
if (IS_IMMUTABLE(inode))
|
||||
return -EPERM;
|
||||
|
||||
if (!inode_owner_or_capable(mnt_userns, inode)) {
|
||||
error = inode_permission(mnt_userns, inode, MAY_WRITE);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(may_setattr);
|
||||
|
||||
/**
|
||||
* notify_change - modify attributes of a filesytem object
|
||||
* @mnt_userns: user namespace of the mount the inode was found from
|
||||
@ -290,25 +318,9 @@ int notify_change(struct user_namespace *mnt_userns, struct dentry *dentry,
|
||||
|
||||
WARN_ON_ONCE(!inode_is_locked(inode));
|
||||
|
||||
if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
|
||||
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/*
|
||||
* If utimes(2) and friends are called with times == NULL (or both
|
||||
* times are UTIME_NOW), then we need to check for write permission
|
||||
*/
|
||||
if (ia_valid & ATTR_TOUCH) {
|
||||
if (IS_IMMUTABLE(inode))
|
||||
return -EPERM;
|
||||
|
||||
if (!inode_owner_or_capable(mnt_userns, inode)) {
|
||||
error = inode_permission(mnt_userns, inode, MAY_WRITE);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
error = may_setattr(mnt_userns, inode, ia_valid);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if ((ia_valid & ATTR_MODE)) {
|
||||
umode_t amode = attr->ia_mode;
|
||||
|
@ -1985,8 +1985,8 @@ static int gfs2_setattr(struct user_namespace *mnt_userns,
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
error = -EPERM;
|
||||
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
|
||||
error = may_setattr(&init_user_ns, inode, attr->ia_valid);
|
||||
if (error)
|
||||
goto error;
|
||||
|
||||
error = setattr_prepare(&init_user_ns, dentry, attr);
|
||||
|
@ -3439,6 +3439,8 @@ extern int buffer_migrate_page_norefs(struct address_space *,
|
||||
#define buffer_migrate_page_norefs NULL
|
||||
#endif
|
||||
|
||||
int may_setattr(struct user_namespace *mnt_userns, struct inode *inode,
|
||||
unsigned int ia_valid);
|
||||
int setattr_prepare(struct user_namespace *, struct dentry *, struct iattr *);
|
||||
extern int inode_newsize_ok(const struct inode *, loff_t offset);
|
||||
void setattr_copy(struct user_namespace *, struct inode *inode,
|
||||
|
Loading…
Reference in New Issue
Block a user