mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-24 02:24:28 +08: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);
|
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
|
* notify_change - modify attributes of a filesytem object
|
||||||
* @mnt_userns: user namespace of the mount the inode was found from
|
* @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));
|
WARN_ON_ONCE(!inode_is_locked(inode));
|
||||||
|
|
||||||
if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
|
error = may_setattr(mnt_userns, inode, ia_valid);
|
||||||
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
|
if (error)
|
||||||
return -EPERM;
|
return error;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ia_valid & ATTR_MODE)) {
|
if ((ia_valid & ATTR_MODE)) {
|
||||||
umode_t amode = attr->ia_mode;
|
umode_t amode = attr->ia_mode;
|
||||||
|
@ -1985,8 +1985,8 @@ static int gfs2_setattr(struct user_namespace *mnt_userns,
|
|||||||
if (error)
|
if (error)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
error = -EPERM;
|
error = may_setattr(&init_user_ns, inode, attr->ia_valid);
|
||||||
if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
|
if (error)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
error = setattr_prepare(&init_user_ns, dentry, attr);
|
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
|
#define buffer_migrate_page_norefs NULL
|
||||||
#endif
|
#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 *);
|
int setattr_prepare(struct user_namespace *, struct dentry *, struct iattr *);
|
||||||
extern int inode_newsize_ok(const struct inode *, loff_t offset);
|
extern int inode_newsize_ok(const struct inode *, loff_t offset);
|
||||||
void setattr_copy(struct user_namespace *, struct inode *inode,
|
void setattr_copy(struct user_namespace *, struct inode *inode,
|
||||||
|
Loading…
Reference in New Issue
Block a user